diff options
Diffstat (limited to 'tex/context/base/meta-ini.mkiv')
-rw-r--r-- | tex/context/base/meta-ini.mkiv | 1275 |
1 files changed, 1275 insertions, 0 deletions
diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv new file mode 100644 index 000000000..61acbca32 --- /dev/null +++ b/tex/context/base/meta-ini.mkiv @@ -0,0 +1,1275 @@ +%D \module +%D [ file=meta-ini, +%D version=2008.03.25, +%D title=\METAPOST\ Graphics, +%D subtitle=Initialization, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{MetaPost Graphics / Initializations} + +\unprotect + +%D Instead of sharing code with \MKII, I decided to copy +%D the code. Otherwise maintainance becomes a pain and after all, +%D the \MKII\ code will not change. + +\let \useMETAFUNformattrue\relax \let \useMETAFUNformatfalse\relax +\let \longMPlinestrue\relax \let \longMPlinesfalse\relax +\let \runMPgraphicstrue\relax \let \runMPgraphicsfalse\relax +\let \runMPTEXgraphicstrue\relax \let \runMPTEXgraphicsfalse\relax +\let \MPstaticgraphictrue\relax \let \MPstaticgraphicfalse\relax +\let\forceMPTEXgraphictrue\relax \let\forceMPTEXgraphicfalse\relax + +\let \obeyMPlines\relax +\let \forceMPTEXcheck\gobbleoneargument +\let\maxnofMPgraphics\scratchcounter + +\newtoks \MPextensions % mp, once +\newtoks \MPinitializations % tex, each +\newtoks \MPuserinclusions % mp, user +\newtoks \MPfinalizations % mp, user +\newtoks \everyMPgraphic % mp +\newtoks \everyMPTEXgraphic % tex + +\newif\ifMPrun +\def\MPruntimefile{mprun} + +% The next command is, of course, dedicated to Mojca, who +% needs it for gnuplot. Anyway, the whole multiple engine +% mechanism is to keep her gnuplot from interfering. + +\def\startMPdefinitions + {\dosinglegroupempty\dostartMPdefinitions} + +\long\def\dostartMPdefinitions#1#2\stopMPdefinitions + {\edef\currentMPgraphicinstance{#1}% + \ifx\currentMPgraphicinstance\empty + \let\currentMPgraphicinstance\defaultMPgraphicinstance + \fi + \global\MPinstancetoks\expandafter{\the\MPinstancetoks#2}} + +\long\def\startMPextensions#1\stopMPextensions + {\global\MPextensions\expandafter{\the\MPextensions#1}} + +\long\def\startMPinitializations#1\stopMPinitializations + {\global\MPinitializations\expandafter{\the\MPinitializations#1}} + +\long\def\startMPinclusions + {\dosingleempty\dostartMPinclusions} + +\long\def\dostartMPinclusions[#1]#2\stopMPinclusions + {\doifnot{#1}{+}{\global\MPuserinclusions\emptytoks}% + \global\MPuserinclusions\expandafter{\the\MPuserinclusions#2}} + +\def\MPinclusions + {\dosingleempty\doMPinclusions} + +\long\def\doMPinclusions[#1]#2% + {\doifnot{#1}{+}{\global\MPuserinclusions\emptytoks}% + \global\MPuserinclusions\expandafter{\the\MPuserinclusions#2}} + +\def\presetMPdefinitions + {\edef\overlaywidth {\overlaywidth \space}% + \edef\overlayheight {\overlayheight \space}% + \edef\overlaylinewidth{\overlaylinewidth\space}% + \edef\currentwidth {\the\hsize \space}% + \edef\currentheight {\the\vsize \space}} + +\def\currentMPformat{metafun} + +\def\@@MPF{@MPF@} + +\def\MPinstancetoks{\csname\@@MPF::\currentMPgraphicinstance\endcsname} + +\unexpanded\def\defineMPinstance + {\dodoubleargument\dodefineMPinstance} + +\def\dodefineMPinstance[#1][#2]% + {\ifcsname\@@MPF::#1\endcsname\else\expandafter\newtoks\csname\@@MPF::#1\endcsname\fi + \MPinstancetoks\emptytoks % in case we redefine + \getparameters[\@@MPF#1][\s!format=mpost,\s!extensions=\v!no,\s!initializations=\v!no,#2]} + +\def\resetMPinstance[#1]% + {\writestatus\m!metapost{reset will be implemented when needed}} + +\def\defaultMPgraphicinstance{metafun} + +\def\splitMPgraphicname[#1]% + {\dosplitMPgraphicname[#1::::]} + +\def\dosplitMPgraphicname[#1::#2::#3]% instance :: + {\edef\currentMPgraphicname{#2}% + \ifx\currentMPgraphicname\empty + \edef\currentMPgraphicname{#1}% + \let\currentMPgraphicinstance\defaultMPgraphicinstance + \else + \edef\currentMPgraphicinstance{#1}% + \fi + \edef\currentMPgraphicformat + {\ifcsname\@@MPF\currentMPgraphicinstance\s!format\endcsname + \csname\@@MPF\currentMPgraphicinstance\s!format\endcsname + \else + \defaultMPgraphicinstance + \fi}} + +\def\currentMPgraphicinstance{\defaultMPgraphicinstance} +\def\currentMPgraphicformat {\currentMPgraphicinstance} + +\defineMPinstance[metafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] +\defineMPinstance[extrafun][\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] +\defineMPinstance[mprun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] +\defineMPinstance[metapost][\s!format=mpost] +\defineMPinstance[nofun] [\s!format=mpost] + +\def\beginMPgraphicgroup#1% + {\begingroup + \splitMPgraphicname[#1]} + +\def\endMPgraphicgroup + {\endgroup} + +\newconditional \METAFUNinitialized + +\def\MPaskedfigure{false} + +\def\currentMPinitializations + {\ifconditional\includeMPinitializations\the\MPinitializations;\fi\theMPrandomseed;} + +\def\currentMPpreamble + {\ifconditional\includeMPextensions\the\MPextensions;\the\MPuserinclusions;\fi\the\MPinstancetoks;} + +\def\dostartcurrentMPgraphic + {\begingroup + \enableincludeMPgraphics + \the\everyMPgraphic + \presetMPdefinitions + \setMPrandomseed % this has to change + % we need to preexpand the token lists + \doifelsevalue{\@@MPF\currentMPgraphicinstance\s!extensions}\v!yes + {\settrue \includeMPextensions\letgvalue{\@@MPF\currentMPgraphicinstance\s!extensions}\v!no} + {\setfalse\includeMPextensions}% + \doifelsevalue{\@@MPF\currentMPgraphicinstance\s!initializations}\v!yes + {\settrue \includeMPinitializations}% + {\setfalse\includeMPinitializations}} + +\def\dostopcurrentMPgraphic + {\global\MPinstancetoks\emptytoks + \global\settrue\METAFUNinitialized % becomes obsolete + \endgroup} + +\unexpanded\long\def\processMPgraphic#1% todo: extensions and inclusions outside beginfig + {\dostartcurrentMPgraphic + \forgetall + \setbox\MPgraphicbox\hbox\bgroup + \normalexpanded{\noexpand\ctxlua{metapost.graphic( + "\currentMPgraphicinstance", + "\currentMPgraphicformat", + \!!bs#1\!!es, + \!!bs\currentMPinitializations\!!es, + \!!bs\currentMPpreamble\!!es, + \MPaskedfigure + )}}% + \egroup + \placeMPgraphic + \dostopcurrentMPgraphic} + +\newif\ifsetMPrandomseed \setMPrandomseedtrue % false by default + +\def\setMPrandomseed + {\let\theMPrandomseed\empty + \ifsetMPrandomseed \ifx\getrandomnumber\undefined \else + \getrandomnumber\localMPseed\zerocount{4095}% + \def\theMPrandomseed{randomseed:=\localMPseed}% + \fi\fi} + +%D To be integrated + +\def\@@MPG{@MPG@} + +\def\doifMPgraphicelse#1% + {\ifcsname\@@MPG#1\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi} + +\def\includeMPgraphic#1% + {\executeifdefined{\@@MPG#1};} % ; if not found + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} + +\let\MPdrawingdata\empty + +\newif\ifMPdrawingdone \MPdrawingdonefalse + +\def\resetMPdrawing + {\globallet\MPdrawingdata\empty + \global\MPdrawingdonefalse} + +\def\pushMPdrawing + {\globalpushmacro\MPdrawingdata + \globallet\MPdrawingdata\empty} + +\def\popMPdrawing + {\globalpopmacro\MPdrawingdata} + +\def\getMPdrawing{\dosinglegroupempty\dogetMPdrawing} + +\def\startMPdrawing + {\dosingleempty\dostartMPdrawing} + +\long\def\dostartMPdrawing[#1]#2\stopMPdrawing + {\relax + \bgroup + \enableincludeMPgraphics + \presetMPdefinitions % in case #2 has measures + \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}% + \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}% + \egroup} + +\let\stopMPdrawing\relax + +\let\MPdrawingdata\empty + +\newif\ifMPshiftdrawing \MPshiftdrawingfalse + +\def\resetMPdrawing + {\globallet\MPdrawingdata\empty + \global\MPdrawingdonefalse} + +\def\pushMPdrawing + {\globalpushmacro\MPdrawingdata + \globallet\MPdrawingdata\empty} + +\def\popMPdrawing + {\globalpopmacro\MPdrawingdata} + +\def\getMPdrawing + {\ifMPdrawingdone + \expandafter\processMPgraphic\expandafter{\MPdrawingdata}% is this expansion still needed? + \fi} + +\def\startMPdrawing + {\dosingleempty\dostartMPdrawing} + +\long\def\dostartMPdrawing[#1]#2\stopMPdrawing + {\relax + \bgroup + \enableincludeMPgraphics + \presetMPdefinitions % in case #2 has measures + \doifelse{#1}{-}{\convertargument#2\to\asciia}{\long\def\asciia{#2}}% + \long\xdef\MPdrawingdata{\MPdrawingdata\asciia}% + \egroup} + +\let\stopMPdrawing\relax + +\let\stopMPclip\relax + +\long\def\startMPclip#1#2\stopMPclip % todo: store at the lua end or just store less + {\long\setgvalue{MPC:#1}{#2}} + +\def\grabMPclippath#1#2#3#4#5% #5 is alternative + {\begingroup + \edef\width {#3\space}\let\overlaywidth \width + \edef\height{#4\space}\let\overlayheight\height + \ifcsname MPC:#1\endcsname + \dostartcurrentMPgraphic + \xdef\MPclippath{\normalexpanded{\noexpand\ctxlua{metapost.theclippath( + "\currentMPgraphicinstance", + "\currentMPgraphicformat", + \!!bs\getvalue{MPC:#1}\!!es, + \!!bs\currentMPinitializations\!!es, + \!!bs\currentMPpreamble\!!es + )}}}% + \dostopcurrentMPgraphic + \ifx\MPclippath\empty\xdef\MPclippath{#5}\fi + \else + \xdef\MPclippath{#5}% + \fi + % #2 : method is obsolete, only pdf now, we can always + % gsub the result to ps + \endgroup} + +%D Next we will use these support macros. + +\startMPextensions + if unknown context_tool: input mp-tool; fi; + if unknown context_spec: input mp-spec; fi; + if unknown context_grph: input mp-grph; fi; +\stopMPextensions + +%D Since we want lables to follow the document settings, we +%D also set the font related variables. + +\startMPinitializations % scale is not yet ok + defaultfont:="\truefontname{Regular}"; + defaultscale:=\the\bodyfontsize/10pt; +\stopMPinitializations + +% watch out, this is a type1 font because mp can only handle 8 bit fonts + +\startMPinitializations % scale is not yet ok + defaultfont:="rm-lmtt10"; +\stopMPinitializations + +%D A signal that we're in combines \CONTEXT||\METAFUN mode: + +\startMPextensions + string contextversion; + contextversion:="\contextversion"; +\stopMPextensions + +%D Some safeguards: +%D +%D \starttyping +%D \appendtoks \cleanupfeatures \to \everyMPgraphic +%D \stoptyping +%D +%D No, we don't want that (else we loose UTF etc). + +%D Another one: + +\prependtoks \MPstaticgraphictrue \to \everyoverlay +\prependtoks \MPstaticgraphictrue \to \everypagebody + +%D \macros +%D {setupMPvariables} +%D +%D When we build collections of \METAPOST\ graphics, like +%D background and buttons, the need for passing settings +%D arises. By (mis|)|using the local prefix that belongs to +%D \type {\framed}, we get a rather natural interface to +%D backgrounds. To prevent conflicts, we will use the \type +%D {-} in \METAPOST\ specific variables, like: +%D +%D \starttyping +%D \setupMPvariables[meta:button][size=20pt] +%D \stoptyping + +\def\@@meta{meta:} + +\unexpanded\def\setupMPvariables + {\dodoubleempty\dosetupMPvariables} + +\def\dosetupMPvariables[#1][#2]% + {\ifsecondargument + \getrawparameters[#1:][#2]% brr, todo: [\@@meta#1:] + \else + \getrawparameters[\@@meta][#1]% + \fi} + +\let\@@framed\s!unknown + +\def\MPvariable#1% + {\csname + \ifcsname\@@framed\@@meta#1\endcsname\@@framed\fi\@@meta#1% + \endcsname} + +\let\MPvar\MPvariable + +\let\setMPvariables\setupMPvariables + +\def\MPrawvar#1#2{\csname#1:#2\endcsname} + +\def\presetMPvariable + {\dodoubleargument\dopresetMPvariable} + +\def\dopresetMPvariable[#1][#2=#3]% + {\ifcsname#1:#2\endcsname\else\setvalue{#1:#2}{#3}\fi} + +\def\useMPvariables + {\dodoubleargument\douseMPvariables} + +\def\douseMPvariables[#1][#2]% + {\def\@@meta{#1:}% + \prepareMPvariables{#2}} + +%D \macros +%D {startuniqueMPgraphic, uniqueMPgraphic} +%D +%D This macros is probably of most use to myself, since I like +%D to use graphics that adapt themselves. The next \METAPOST\ +%D kind of graphic is both unique and reused when possible. +%D +%D \starttyping +%D \defineoverlay[example][\uniqueMPgraphic{test}] +%D +%D \startuniqueMPgraphic {test} +%D draw unitsquare xscaled \overlaywidth yscaled \overlayheight ; +%D \stopuniqueMPgraphic +%D \stoptyping + +\def\overlaystamp % watch the \MPcolor, since colors can be redefined + {\overlaywidth:\overlayheight:\overlaydepth:\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +%D A better approach is to let additional variables play a role +%D in determining the uniqueness. In the next macro, the +%D second, optional, argument is used to guarantee the +%D uniqueness, as well as prepare variables for passing them to +%D \METAPOST. +%D +%D \starttyping +%D \startuniqueMPgraphic{meta:hash}{gap,angle,...} +%D \stoptyping +%D +%D The calling macro also accepts a second argument. For +%D convenient use in overlay definitions, we use \type {{}} +%D instead of \type {[]}. +%D +%D \starttyping +%D \uniqueMPgraphic{meta:hash}{gap=10pt,angle=30} +%D \stoptyping + +\newcount\MPobjectcounter +\newbox \MPgraphicbox + +\chardef\MPboxmode\zerocount + +\def\doobeyMPboxdepth % mode = 1 + {\setbox\MPgraphicbox\hbox{\hskip\MPllx\onebasepoint\raise\MPlly\onebasepoint\box\MPgraphicbox}} + +\def\doignoreMPboxdepth % mode = 2 + {\normalexpanded + {\noexpand\doobeyMPboxdepth + \wd\MPgraphicbox\the\wd\MPgraphicbox + \ht\MPgraphicbox\the\ht\MPgraphicbox + \dp\MPgraphicbox\the\dp\MPgraphicbox}} + +\def\obeyMPboxdepth {\chardef\MPboxmode\plusone} +\def\ignoreMPboxdepth{\chardef\MPboxmode\plustwo} +\def\normalMPboxdepth{\chardef\MPboxmode\zerocount} + +% compatibility hack: + +\let\MPshiftdrawingtrue \ignoreMPboxdepth +\let\MPshiftdrawingfalse\normalMPboxdepth + +\unexpanded\def\placeMPgraphic + {\ifcase\MPboxmode + \or % 1 + \doobeyMPboxdepth + \or % 2 + \doignoreMPboxdepth + \fi + \box\MPgraphicbox} + +\def\reuseMPbox#1#2#3#4#5% space delimiting would save some tokens + {\xdef\MPllx{#2}% but it's not worth the effort and looks + \xdef\MPlly{#3}% ugly as well + \xdef\MPurx{#4}% + \xdef\MPury{#5}% + \hbox{\forcecolorhack\getobject{MP}{#1}}} % else no proper color intent + +\long\def\handleuniqueMPgraphic#1#2#3% + {\begingroup + \def\@@meta{#1:}% + \extendMPoverlaystamp{#2}% incl prepare + \ifcsname\@@MPG\overlaystamp:#1\endcsname\else + \enableincludeMPgraphics % redundant + \global\advance\MPobjectcounter\plusone + \setobject{MP}{\number\MPobjectcounter}\hbox{\processMPgraphic{#3}}% was vbox, graphic must end up as hbox + \setxvalue{\@@MPG\overlaystamp:#1}{\noexpand\reuseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}% + \fi + \getvalue{\@@MPG\overlaystamp:#1}% + \endgroup} + +\long\unexpanded\def\startuniqueMPgraphic + {\dodoublegroupempty\dostartuniqueMPgraphic} + +\long\def\dostartuniqueMPgraphic#1#2#3\stopuniqueMPgraphic% + {\long\setgvalue{\@@MPG#1}{\handleuniqueMPgraphic{#1}{#2}{#3}}} + +\unexpanded\def\uniqueMPgraphic + {\dodoublegroupempty\douniqueMPgraphic} + +\def\douniqueMPgraphic#1#2% + {\beginMPgraphicgroup{#1}% + \setupMPvariables[\currentMPgraphicname][#2]% + \getvalue{\@@MPG\currentMPgraphicname}\empty + \endMPgraphicgroup} + +\let\stopuniqueMPcode \relax % so that we can use it in \expanded + +\long\def\handleuseMPgraphic#1#2#3% + {\begingroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics % redundant + \processMPgraphic{#3}% + \endgroup} + +\long\unexpanded\def\startuseMPgraphic + {\dodoublegroupempty\dostartuseMPgraphic} + +\long\def\dostartuseMPgraphic#1#2#3\stopuseMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}} + +\long\unexpanded\def\startusableMPgraphic % redundant but handy + {\dodoublegroupempty\dostartusableMPgraphic} + +\long\def\dostartusableMPgraphic#1#2#3\stopusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handleuseMPgraphic{#1}{#2}{#3}}} + +\let\stopuseMPgraphic \relax % so that we can use it in \expanded +\let\stopusableMPgraphic \relax % so that we can use it in \expanded + +\long\def\handlereusableMPgraphic#1#2#3% + {\begingroup + \def\@@meta{#1:}% + \prepareMPvariables{#2}% + \enableincludeMPgraphics % redundant + \global\advance\MPobjectcounter\plusone + \setobject{MP}{\number\MPobjectcounter}\hbox{\processMPgraphic{#3}}% was vbox, graphic must end up as hbox + \setxvalue{\@@MPG#1}{\noexpand\reuseMPbox{\number\MPobjectcounter}{\MPllx}{\MPlly}{\MPurx}{\MPury}}% + \getvalue{\@@MPG#1}% + \endgroup} + +\long\unexpanded\def\startreusableMPgraphic + {\dodoublegroupempty\dostartreusableMPgraphic} + +\long\def\dostartreusableMPgraphic#1#2#3\stopreusableMPgraphic + {\long\setgvalue{\@@MPG#1}{\handlereusableMPgraphic{#1}{#2}{#3}}} + +\let\stopreusableMPgraphic \relax % so that we can use it in \expanded + +\unexpanded\def\useMPgraphic + {\dodoublegroupempty\douseMPgraphic} + +\def\douseMPgraphic#1#2% + {\beginMPgraphicgroup{#1}% + \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% + \getvalue{\@@MPG\currentMPgraphicname}\empty + \endMPgraphicgroup} + +\let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed +\let\reusableMPgraphic\reuseMPgraphic % we can save a setup here if needed + +\let\stopuseMPcode \relax % so that we can use it in \expanded +\let\stopusableMPcode \relax % so that we can use it in \expanded +\let\stopreusableMPcode \relax % so that we can use it in \expanded +\let\stopuniqueMPcode \relax % so that we can use it in \expanded + +\def\enableincludeMPgraphics + {\let\handleuseMPgraphic \thirdofthreearguments + \let\handlereusableMPgraphic\thirdofthreearguments} + +%D \macros +%D {startuniqueMPpagegraphic,uniqueMPpagegraphic} +%D +%D Experimental. + +\def\MPpageprefix{\doifoddpageelse oe:} + +\def\overlaypagestamp + {\MPpageprefix\overlaywidth:\overlayheight:\overlaydepth:\MPcolor\overlaycolor:\MPcolor\overlaylinecolor} + +\long\unexpanded\def\startuniqueMPpagegraphic + {\dodoublegroupempty\dostartuniqueMPpagegraphic} + +\long\def\dostartuniqueMPpagegraphic#1#2#3\stopuniqueMPpagegraphic + {\long\setgvalue{\@@MPG o:#1}{\handleuniqueMPgraphic{o:#1}{#2}{#3}}% + \long\setgvalue{\@@MPG e:#1}{\handleuniqueMPgraphic{e:#1}{#2}{#3}}} + +\unexpanded\def\uniqueMPpagegraphic + {\dodoublegroupempty\douniqueMPpagegraphic} + +\def\douniqueMPpagegraphic#1#2% + {\beginMPgraphicgroup{#1}% + \let\overlaystamp\overlaypagestamp + \setupMPvariables[\MPpageprefix\currentMPgraphicname][#2]% prefix is new here + \getvalue{\@@MPG\MPpageprefix\currentMPgraphicname}{}% + \endMPgraphicgroup} + +%D One way of defining a stamp is: +%D +%D \starttyping +%D \def\extendMPoverlaystamp#1% +%D {\def\docommand##1% +%D {\edef\overlaystamp{\overlaystamp:\MPvariable{##1}}}% +%D \processcommalist[#1]\docommand} +%D \stoptyping + +%D Since we need to feed \METAPOST\ with expanded dimensions, +%D we introduce a dedicated expansion engine. + +\def\prepareMPvariable#1% + {\ifcsname\@@framed\@@meta#1\endcsname + \doprepareMPvariable{\@@framed\@@meta#1}% + \else + \doprepareMPvariable{\@@meta#1}% + \fi} + +% \startlines +% \def\xxx{\lineheight} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2pt} \doprepareMPvariable{xxx} \xxx +% \def\xxx{2} \doprepareMPvariable{xxx} \xxx +% \def\xxx{\scratchcounter} \doprepareMPvariable{xxx} \xxx +% \def\xxx{red} \doprepareMPvariable{xxx} \xxx +% \def\xxx{0.4} \doprepareMPvariable{xxx} \xxx +% \stoplines + +\def\doprepareMPvariable#1% + {\edef\theMPvariable{\getvalue{#1}}% + \doifelsenothing\theMPvariable + {\setevalue{#1}{\MPcolor{black}}} + {\defconvertedcommand\ascii\theMPvariable % otherwise problems + \doifcolorelse \ascii % with 2\bodyfontsize + {\setevalue{#1}{\MPcolor\theMPvariable}} + {% can be aux macro + \setbox\scratchbox\hbox{\scratchdimen\theMPvariable sp}% + \ifdim\wd\scratchbox=\zeropoint + % \scratchcounter\theMPvariable + % \setevalue{#1}{\the\scratchcounter}% + % also accepts 0.number : + \setevalue{#1}{\number\theMPvariable}% + \else + \scratchdimen\theMPvariable + \setevalue{#1}{\the\scratchdimen}% + \fi}}} + +%D We redefine \type {\extendMPoverlaystamp} to preprocess +%D variables using \type {\prepareMPvariable}. + +\def\doextendMPoverlaystamp#1% + {\prepareMPvariable{#1}% + \edef\overlaystamp{\overlaystamp:\MPvariable{#1}}} + +\def\extendMPoverlaystamp#1% + {\processcommalist[#1]\doextendMPoverlaystamp} + +\def\prepareMPvariables#1% + {\processcommalist[#1]\prepareMPvariable} + +%D \macros +%D {MPdatafile} +%D +%D We redefine a macro from \type {supp-mps.tex}: + +\def\MPdataMPDfile{\jobname-mpgraph.mpd} +\def\MPdataMPOfile{\jobname-mpgraph.mpo} +\def\MPdataMPYfile{\jobname-mpgraph.mpy} + +\startMPextensions + boolean collapse_data; collapse_data:=true; + def data_mpd_file = "\MPdataMPDfile" enddef ; + def data_mpo_file = "\MPdataMPOfile" enddef ; + def data_mpy_file = "\MPdataMPYfile" enddef ; +\stopMPextensions + +\chardef\currentMPgraphic\plusone + +\def\getMPdata + {\let\MPdata\secondoftwoarguments + \startreadingfile + % \startnointerference % no, else we need to do all data global + \readlocfile\MPdataMPDfile\donothing\donothing + % \stopnointerference + \stopreadingfile} + +%D \macros +%D {MPrunfile} +%D +%D This one is more abstract and does not assume knowledge +%D of buffer prefixes. + +\def\MPrunfile#1% + {\bufferprefix mprun.#1} + +%D For the moment, the next one is a private macro: + +\def\processMPbuffer + {\dosingleempty\doprocessMPbuffer} + +\def\doprocessMPbuffer[#1]% + {\doifelsenothing{#1} + {\dodoprocessMPbuffer{\jobname}} + {\dodoprocessMPbuffer{#1}}} + +% we need to go via a toks because we have no multiline print in +% luatex (i.e. tex.sprint does not interpret lines) and therefore +% omits all after a comment token + +\newtoks\mpbuffertoks + +\def\doprocessMPbuffer[#1]% + {\doifelsenothing{#1} + {\doprocessMPbuffer[\jobname]} + {\beginMPgraphicgroup{#1}% + % we need this trick because tex.sprint does not interprets newlines and the scanner + % stops at a newline; also, we do need to flush the buffer under a normal catcode + % regime in order to expand embedded tex macros; #1 can be a list + \processMPgraphic{\ctxlua{buffers.feedback("\currentMPgraphicname")}}% + \endMPgraphicgroup}} + +\def\runMPbuffer + {\dosingleempty\dorunMPbuffer} + +\def\dorunMPbuffer[#1]% processing only + {\startnointerference\doprocessMPbuffer[#1]\stopnointerference} + +%D \macros +%D {startMPenvironment, resetMPenvironment} +%D +%D In order to synchronize the main \TEX\ run and the runs +%D local to \METAPOST, environments can be passed. + +\ifx\everyMPTEXgraphic\undefined + \newtoks\everyMPTEXgraphic +\fi + +%D A more general way of passing environments is: + +\def\startMPenvironment % second arg gobbles spaces, so that reset gives \emptytoks + {\dodoubleempty\dostartMPenvironment} + +\long\def\dostartMPenvironment[#1][#2]#3\stopMPenvironment + {\doif{#1}\s!reset\resetMPenvironment % reset mp toks + \doif{#1}\v!global{#3}% % use in main doc too + \doif{#1}+{#3}% % use in main doc too + \ctxlua{metapost.tex.set(\!!bs\detokenize{#3}\!!es)}} + +\def\resetMPenvironment + {\ctxlua{metapost.tex.reset()}} + +\resetMPenvironment + +\def\useMPenvironmentbuffer[#1]% + {\ctxlua{metapost.tex.set(buffers.content("#1"))}} + +%D This command takes \type {[reset]} as optional +%D argument. +%D +%D \starttyping +%D \startMPenvironment +%D \setupbodyfont[pos,14.4pt] +%D \stopMPenvironment +%D +%D \startMPcode +%D draw btex \sl Hans Hagen etex scaled 5 ; +%D \stopMPcode +%D \stoptyping +%D +%D The most simple case: + +\def\startMPcode{\dosinglegroupempty\dostartMPcode} + +\def\dostartMPcode + {\iffirstargument + \expandafter\dodostartMPcode + \else + \expandafter\nodostartMPcode + \fi} + +\def\dodostartMPcode#1#2\stopMPcode + {\beginMPgraphicgroup{#1::\s!dummy}% name does not matter + \processMPgraphic{#2}% + \endMPgraphicgroup} + +\def\nodostartMPcode#1#2\stopMPcode + {\processMPgraphic{#2}} + +\let\stopMPcode\relax + +% a bit nasty (also needed for compatibility: + +% \startMPrun input mp-www.mp ; \stopMPrun +% \externalfigure[mprun.3][width=10cm,height=8cm] + +% \startMPrun{mprun} input mp-www.mp ; \stopMPrun % instance +% \externalfigure[mprun.4][width=10cm,height=8cm] + +\let\MPruninstance\defaultMPgraphicinstance + +\def\useMPrun#1#2% name n + {\begingroup + \def\MPaskedfigure{#2}% + \doifelsenothing{#1} + {\useMPgraphic{mprun}}% + {\useMPgraphic{#1}}% + \endgroup} + +\def\startMPrun + {\dosinglegroupempty\dostartMPrun} + +\long\def\dostartMPrun#1#2\stopMPrun + {\iffirstargument + \startuseMPgraphic{#1}#2\stopuseMPgraphic + \else + \startuseMPgraphic{mprun}#2\stopuseMPgraphic + \fi} + +% for old time sake + +\def\dostartMPgraphic + {\iffirstargument + \expandafter\dodostartMPgraphic + \else + \expandafter\nodostartMPgraphic + \fi} + +\def\dodostartMPgraphic#1#2\stopMPgraphic + {\beginMPgraphicgroup{#1::\s!dummy}% name does not matter + \processMPgraphic{#2}% + \endMPgraphicgroup} + +\def\nodostartMPgraphic#1#2\stopMPcode + {\processMPgraphic{#2}} + +\let\stopMPcode\relax + +%D The \type {\resetMPenvironment} is a quick way to erase +%D the token list. +%D +%D You should be aware of independencies. For instance, if you use a font +%D in a graphic that is not used in the main document, you need to load the +%D typescript at the outer level (either directly or by using the global +%D option). +%D +%D \starttyping +%D \usetypescript[palatino][texnansi] +%D +%D \startMPenvironment +%D \usetypescript[palatino][texnansi] +%D \enableregime[utf] +%D \setupbodyfont[palatino] +%D \stopMPenvironment +%D +%D \startMPpage +%D draw btex aap‒noot coördinatie – één etex ; +%D \stopMPpage +%D \stoptyping + +%D Loading specific \METAPOST\ related definitions is +%D accomplished by: + +\def\douseMPlibrary#1% + {\ifcsname\c!file\f!metapostprefix#1\endcsname\else + \letvalueempty{\c!file\f!metapostprefix#1}% + \makeshortfilename[\truefilename{\f!metapostprefix#1}]% + \startreadingfile + \readsysfile\shortfilename{\showmessage\m!metapost1{#1}}\donothing + \stopreadingfile + \fi} + +\def\useMPlibrary[#1]% + {\processcommalist[#1]\douseMPlibrary} + +%D \macros +%D {setMPtext, MPtext, MPstring, MPbetex} +%D +%D To be documented: +%D +%D \starttyping +%D \setMPtext{identifier}{text} +%D +%D \MPtext {identifier} +%D \MPstring{identifier} +%D \MPbetex {identifier} +%D \stoptyping + +\def\@@MPT{@MPT@} + +\def\forceMPTEXgraphic + {\long\def\checkMPTEXgraphic##1{\global\MPTEXgraphictrue}} + +\def\setMPtext#1#2% todo : #1 must be made : safe + {%\forceMPTEXgraphic + \defconvertedargument\ascii{#2}% + \dodoglobal\letvalue{\@@MPT#1}\ascii} + +\def\MPtext #1{\executeifdefined{\@@MPT#1}\empty} +\def\MPstring #1{"\executeifdefined{\@@MPT#1}\empty"} +\def\MPbetex #1{btex \executeifdefined{\@@MPT#1}\empty\space etex} + +%D Unfortunately \METAPOST\ does not have \CMYK\ support +%D built in, but by means of specials we can supply the +%D information needed to handle them naturaly. + +% \newif\ifMPcmykcolors \MPcmykcolorstrue +% \newif\ifMPspotcolors \MPspotcolorstrue + +\startMPinitializations + cmykcolors:=\ifMPcmykcolors true\else false\fi; + spotcolors:=\ifMPspotcolors true\else false\fi; +\stopMPinitializations + +%D In order to communicate conveniently with the \TEX\ +%D engine, we introduce some typesetting variables. + +\startMPextensions + color OverlayColor,OverlayLineColor; +\stopMPextensions + +\startMPinitializations + OverlayWidth:=\overlaywidth; + OverlayHeight:=\overlayheight; + OverlayDepth:=\overlayheight; + OverlayColor:=\MPcolor{\overlaycolor}; + OverlayLineWidth:=\overlaylinewidth; + OverlayLineColor:=\MPcolor{\overlaylinecolor}; + % + BaseLineSkip:=\the\baselineskip; + LineHeight:=\the\baselineskip; + BodyFontSize:=\the\bodyfontsize; + % + TopSkip:=\the\topskip; + StrutHeight:=\strutheight; + StrutDepth:=\strutdepth; + % + CurrentWidth:=\the\hsize; + CurrentHeight:=\the\vsize; + % + EmWidth:=\the\emwidth; + ExHeight:=\the\exheight; + % + PageNumber:=\the\pageno; + RealPageNumber:=\the\realpageno; + LastPageNumber:= \lastpage; +\stopMPinitializations + +\appendtoks + \disablediscretionaries + \disablecompoundcharacters +\to \everyMPgraphic + +\appendtoks % before color + %\normalexpanded{\noexpand\definecolor[currentcolor][\currentcolorname]}% + \doregistercolor{currentcolor}\currentcolorname +\to \everyMPgraphic + +% \color[green]{abc \startMPcode +% fill fullcircle scaled 3cm withoutcolor; +% fill fullcircle scaled 2cm withcolor \MPcolor{currentcolor} ; +% fill fullcircle scaled 1cm withcolor \MPcolor{red} ; +% \stopMPcode def} + +% \appendtoks +% \doactivatecolor\s!black\forcecolorhack % we can also move this to the backend +% \to \everyMPgraphic + +\appendtoks + \baselineskip1\baselineskip + \lineheight 1\lineheight + \topskip 1\topskip +\to \everyMPgraphic + +\appendtoks + \let \# \letterhash + \let \_ \letterunderscore + \let \& \letterampersand + \let \{ \letteropenbrace + \let \} \letterclosebrace +\to \everyMPgraphic + +\startMPinitializations + prologues:=0; + mpprocset:=1; +\stopMPinitializations + +%D \macros +%D {PDFMPformoffset} +%D +%D In \PDF, forms are clipped and therefore we have to take +%D precautions to get this right. Since this is related to +%D objects, we use the same offset as used there. + +\def\PDFMPformoffset{\objectoffset} + +% %D \macros +% %D {insertMPfile} +% %D +% %D Bypassing the special driver and figure mechanism is not +% %D that nice but saves upto 5\% time in embedding \METAPOST\ +% %D graphics by using the low level \PDF\ converter directly, +% %D given of course that we use \PDFTEX. As a result we need to +% %D fool around with the object trigger. + +\newtoks\everyinsertMPfile + +% removed in backend: +% +% \def\doinsertMPfile#1% +% {\doiffileelse{./#1}{\includeMPasPDF{./#1}}{\message{[MP #1]}}} +% +% \let\insertMPfileARG\insertMPfile +% +% \def\insertMPfile#1#2% in context #2 is empty +% {\doifelsenothing{#2}{\doinsertMPfile{#1}}{\insertMPfileARG{#1}{#2}}} +% +% \def\includeMPasEPS#1% untested !! +% {\bgroup +% \message{[MP as EPS #1]}% +% \the\everyinsertMPfile +% \dogetEPSboundingbox{#1}\!!widtha\!!heighta\!!widthb\!!heightb +% \setbox\scratchbox\vbox to \!!heightb +% {\vfill +% \let \@@DriverImageType \c!mps +% \def \@@DriverImageFile {#1}% +% \edef\@@DriverImageWidth {\the\!!widthb }% +% \edef\@@DriverImageHeight{\the\!!heightb}% +% \doinsertfile}% +% \wd\scratchbox\!!widthb +% \dp\scratchbox\zeropoint +% \box\scratchbox +% \egroup} +% +% \def\includeMPasPDF#1% +% {\bgroup +% \the\everyinsertMPfile +% \ifinobject \else \chardef\makeMPintoPDFobject\plustwo \fi % when needed +% \convertMPtoPDF{#1}{1}{1}% no \plusone ! +% \egroup} +% +% %D So, using a low level approach (thereby avoiding the slower +% %D figure analysis macros) pays off. This kind of +% %D optimizations are a bit tricky since we must make sure that +% %D special resources end up in the (PDF) files. Because the +% %D \METAPOST\ to \PDF\ can handle objects itself, it is not +% %D that complicated. +% +% %D We hook a couple of initializations into the graphic +% %D macros. +% +% \appendtoks +% \let\figuretypes\c!mps +% \runutilityfilefalse +% \consultutilityfilefalse +% \to \everyinsertMPfile +% +% %D One more: (still needed?) + +\startMPextensions + def initialize_form_numbers = + do_initialize_numbers; + enddef; +\stopMPextensions + +\startMPinitializations + HSize:=\the\hsize ; + VSize:=\the\vsize ; +\stopMPinitializations + +\startMPextensions + vardef ForegroundBox = + unitsquare xysized(HSize,VSize) + enddef ; + vardef PageFraction = + if \lastpage>1: (\realfolio-1)/(\lastpage-1) else: 1 fi + enddef ; +\stopMPextensions + +%D And some more. These are not really needed since we +%D don't use the normal figure inclusion macros any longer. + +\appendtoks + \externalfigurepostprocessors\emptytoks % safeguard +\to \everyinsertMPfile + +%D We also take care of disabling fancy figure features, that +%D can terribly interfere when dealing with symbols, +%D background graphics and running (postponed) graphics. +%D You won't believe me if I tell you what funny side effects +%D can occur. One took me over a day to uncover when +%D processing the screen version of the \METAFUN\ manual. + +%D For my eyes only: + +\def\doifelseMPgraphic#1{\doifdefinedelse{\@@MPG#1}} + +%D \macros +%D {startMPcolor} + +\long\unexpanded\def\startMPcolor#1\stopMPcolor + {\writestatus \m!metapost % eventually this placeholder will go away + {\string\startMPcolor...\stopMPcolor\space is obsolete,\space + use \string\defineintermediatecolor\space instead}} + +\let\stopMPcolor\relax + +%D New: + +\definelayerpreset % no dx,dy - else nasty non-mp placement + [mp] + [\c!y=-\MPury bp, + \c!x=\MPllx bp, + \c!method=\v!fit] + +\definelayer + [mp] + [\c!preset=mp] + +%D Usage: +%D +%D \starttyping +%D \defineproperty[one][layer][state=start] +%D \defineproperty[two][layer][state=stop] +%D +%D \startuseMPgraphic{step-1} +%D fill fullcircle scaled 10cm withcolor red ; +%D \stopuseMPgraphic +%D +%D \startuseMPgraphic{step-2} +%D fill fullcircle scaled 5cm withcolor green ; +%D \stopuseMPgraphic +%D +%D \setlayer[mp]{\property[one]{\useMPgraphic{step-1}}} +%D \setlayer[mp]{\property[two]{\useMPgraphic{step-2}}} +%D +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping +%D +%D Reusing graphics is also possible (now): +%D +%D \starttyping +%D \startreusableMPgraphic{axis} +%D tickstep := 1cm ; ticklength := 2mm ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D tickstep := tickstep/2 ; ticklength := ticklength/2 ; +%D drawticks unitsquare xscaled 4cm yscaled 3cm shifted (-1cm,-1cm) ; +%D \stopreusableMPgraphic +%D +%D \startuseMPgraphic{demo} +%D drawpoint "1cm,1.5cm" ; +%D \stopuseMPgraphic +%D +%D \definelayer[mp][preset=mp] +%D \setlayer[mp]{\reuseMPgraphic{axis}} +%D \setlayer[mp]{\useMPgraphic{demo}} +%D \ruledhbox{\flushlayer[mp]} +%D \stoptyping + +%D \macros +%D {startstaticMPfigure,useMPstaticfigure} +%D +%D Static figures are processed only when there has been +%D something changed. Here is Aditya Mahajan's testcase: +%D +%D \startbuffer +%D \startstaticMPfigure{circle} +%D fill fullcircle scaled 1cm withcolor blue; +%D \stopstaticMPfigure +%D +%D \startstaticMPfigure{axis} +%D drawarrow (0,0)--(2cm,0) ; +%D drawarrow (0,0)--(0,2cm) ; +%D label.llft(textext("(0,0)") ,origin) ; +%D \stopstaticMPfigure +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\def\usestaticMPfigure + {\dodoubleempty\dousestaticMPfigure} + +\def\dousestaticMPfigure[#1][#2]% + {\ifsecondargument + \scale[#2]{\reuseMPgraphic{\@@MPG#1@S@}}% + \else + \reuseMPgraphic{\@@MPG#1@S@}% + \fi} + +\unexpanded\def\startstaticMPfigure#1#2\stopstaticMPfigure + {\startreusableMPgraphic{\@@MPG#1@S@}#2\stopreusableMPgraphic} + +\long\unexpanded\def\startstaticMPgraphic + {\dodoublegroupempty\dostartstaticMPgraphic} + +\long\def\dostartstaticMPgraphic#1#2#3\stopstaticMPgraphic + {\long\setgvalue{\@@MPG#1@S@}{\handlereusableMPgraphic{#1}{#2}{#3}}} + +%D New: + +\newconditional\manyMPspecials % when set to true, > 1000 specials can be used + +\settrue \manyMPspecials % per 1/4/2006 + +\prependtoks + _special_div_ := 1000\ifconditional\manyMPspecials0\fi ; +\to \MPextensions + +%D Needed too. + +\let\initializeMPgraphics\relax + +%D Goody for preventing overflows: + +\def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax} + +%D There is no way to distinguish the black color that you get when +%D you issue a \type {draw} without color specification from a color +%D that has an explicit black specification unless you set the +%D variable \type {defaultcolormodel} to 1. Hoewever, in that case +%D you cannot distinguish that draw from one with a \type +%D {withoutcolor} specification. This means that we have to provide +%D multiple variants of inheritance. +%D +%D In any case we need to tell the converter what the inherited color +%D is to start with. Case~3 is kind of unpredictable as it closely +%D relates to the order in which paths are flushed. If you want to +%Dinherit automatically from the surrounding, you can best stick to +%D variant 1. Variant 0 (an isolated graphic) is the default. +%D +%D \startbuffer +%D \startuseMPgraphic{test} +%D drawoptions(withpen pencircle scaled 1pt) ; +%D def shift_cp = currentpicture := currentpicture shifted (-15pt,0) ; enddef ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt ; shift_cp ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt withcolor red ; shift_cp ; +%D draw fullcircle scaled 10pt withoutcolor ; shift_cp ; +%D fill fullcircle scaled 10pt ; shift_cp ; +%D \stopuseMPgraphic +%D +%D \starttabulate +%D \NC 0\quad \NC \chardef\MPcolormethod0 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 1\quad \NC \chardef\MPcolormethod1 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 2\quad \NC \chardef\MPcolormethod2 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \NC 3\quad \NC \chardef\MPcolormethod3 \green XX\quad \useMPgraphic{test}\quad XX \NC \NR +%D \stoptabulate +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +\chardef\MPcolormethod\zerocount + +% can be faster, just + +\appendtoks + \ctxlua{metapost.set_outer_color(\number\MPcolormethod,\number\currentcolormodel,\number\dogetattribute{color},\number\dogetattribute{transparency})}% +\to \everyMPgraphic + +\startMPinitializations + defaultcolormodel := \ifcase\MPcolormethod1\or1\or3\else3\fi; +\stopMPinitializations + +%D \macros +%D {setupMPgraphics} +%D +%D Here is a generic setup command: + +\newtoks \everysetupMPgraphics + +\unexpanded\def\setupMPgraphics[#1]% + {\getparameters[\??mp][#1]% + \the\everysetupMPgraphics} + +%D Here we hook in the outer color. When \type {color} is set to \type +%D {global} we get the outer color automatically. If you change this +%D setting, you should do it grouped in order not to make other graphics +%D behave in unexpected ways. + +\appendtoks + \doifelse\@@mpcolor\v!global{\chardef\MPcolormethod\plusone}{\chardef\MPcolormethod\zerocount}% +\to \everysetupMPgraphics + +\setupMPgraphics + [\c!color=\v!local] + +%D Done. + +\protect \endinput |