%D \module %D [ file=m-chart, %D version=1998.10.10, %D title=\CONTEXT\ Modules, %D subtitle=Flow Charts, %D author={Hans Hagen \& Ton Otten}, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. % todo: \localpushmacro/\localpopmacro (dohandleflowchart etc) % todo: make mkiv variant % todo: use dimexpr/numspr % will be redone with layers and dimexpr or even better, by just using % textext .. a nice example of old code %D This is an experimental module. Pieces of code will be moved %D to other modules. More features are possible but will be %D interfaces later. %D %D When finished this module will be documented. The main macro %D is still a rather big one and there is some redundant and %D slow code that needs a clean up. % arrow, dash % crossing % \goto -> \normalgoto % class -> class:name (ref prefix) % c, automatisch geen overlap zoeken % eind eerder chart connecties % relateren aan korps % check op bestaan naam, bestaan shape % auto als extern figuur % subchart % pijlen % focus % ook nog \MPmessage % areapath -> krappe vlak % clippath -> gehele vlak % % offset : clip offset % breedte : breedte cel % hoogte : hoogte cel % dx : halve afstand in breedte (grid breedte = breedte + 2dx) % dy : halve afstand in hoogte (grid hoogte = hoogte + 2dy) % x : x offset (clipping) % y : y offset (clipping) % nx : minimaal aantal cellen horizontaal % ny : minimaal aantal cellen vertikaal % % shape none en geen equivalent maken % % kaderkleur achtergrondkleur % lijnkleur lijndikte % focus focuskaderkleur focusachtergrondkleur % richting % % focus koppelen aan kleur \unprotect \definesorting [flowchart] [flowcharts] [\v!none] % no access \setupsorting [flowchart] [\c!state=\v!stop] % off by default \def\@FLOW@{@FLOW@} \def\@FLOC@{@FLOC@} \def\@FLOX@{@FLOX@} \def\@@FLOW{@@FLOW} \def\@@FLOL{@@FLOL} \def\@@FLOS{@@FLOS} \def\@@FLOF{@@FLOF} \def\@@FLOT{@@FLOT} \def\@@FLOX{@@FLOX} \def\@@MPx {@@MPx} \def\@@MPy {@@MPy} \def\FLOWbufferprefix{flw-} \def\processFLOWbuffer#1{\getbuffer[\FLOWbufferprefix#1]} \def\typeFLOWbuffer #1{\typebuffer[\FLOWbufferprefix#1]} \def\setFLOWname#1#2% funny hack that makes sure that we get {\bgroup % names that are acceptable for METAPOST \lccode`0=`a\lccode`1=`b\lccode`2=`c\lccode`3=`d\lccode`4=`e% \lccode`5=`f\lccode`6=`g\lccode`7=`h\lccode`8=`i\lccode`9=`j% \lccode` =`\_\lccode`-=`\_\lccode`_=`\_% \lowercase{\gdef#1{#2}}% \egroup} % een gobble als default is sneller, en dan alleen setten als % nodig \def\resetFLOWcell {% variables \global\let\FLOWname \empty \global\let\FLOWalign \empty \global\let\FLOWshape \empty \global\let\FLOWlocation \empty \global\let\FLOWtext \empty \global\let\FLOWhelp \empty \global\let\FLOWdestination\empty \global\let\FLOWoverlay \empty \global\let\FLOWfocus \empty \global\let\tFLOWlabel \empty \global\let\bFLOWlabel \empty \global\let\lFLOWlabel \empty \global\let\rFLOWlabel \empty \global\let\bcFLOWlabel \empty \global\let\tcFLOWlabel \empty \global\let\lcFLOWlabel \empty \global\let\rcFLOWlabel \empty \global\let\tFLOWexit \empty \global\let\bFLOWexit \empty \global\let\lFLOWexit \empty \global\let\rFLOWexit \empty % commands \let\name \doFLOWname \let\shape \doFLOWshape \let\destination\doFLOWdestination \let\location \doFLOWlocation \let\focus \doFLOWfocus \let\overlay \doFLOWoverlay \let\figure \doFLOWfigure \let\text \doFLOWtext \let\comment \doFLOWcomment \let\label \doFLOWlabel \let\help \doFLOWhelp \let\connection \doFLOWconnection \let\exit \doFLOWexit % convenience commands \let\locate \doFLOWlocate \let\connect \doFLOWconnect} \let\FLOWcell \s!unknown \let\FLOWshape \s!unknown \let\FLOWdestination\s!unknown \let\FLOWfocus \s!unknown \let\FLOWoverlay \empty \let\FLOWtext \empty \def\doFLOWname#1% {\def\FLOWcell{#1}\setFLOWname\FLOWname{name_#1}\ignorespaces} \def\doFLOWshape#1% {\gdef\FLOWshape{#1}\ignorespaces} \def\doFLOWdestination#1% {\gdef\FLOWdestination{#1}\ignorespaces} \def\doFLOWlocation#1% {\setFLOWlocation#1\end\ignorespaces} \def\doFLOWfocus#1% {\gdef\FLOWfocus{#1}\ignorespaces} \def\doFLOWoverlay#1% {\gdef\FLOWoverlay{#1}\ignorespaces} \def\doFLOWfigure#1% {\defineoverlay[\s!dummy][\overlayfigure{#1}]% \overlay\s!dummy} \def\doFLOWtext {\dosingleempty\dodoFLOWtext} \def\dodoFLOWtext[#1]% % #2% {\gdef\FLOWalign{#1}\gdef\FLOWtext}% {#2}} \def\doFLOWcomment[#1]#2% {\ignorespaces\dogobblesingleempty} \def\doFLOWlabel[#1]#2% wordt dit gebruikt ? {\setgvalue{#1FLOWlabel}{#2}\ignorespaces} \def\doFLOWhelp#1% {\gdef\FLOWhelp{#1}\ignorespaces} \def\doFLOWconnection {\dodoubleempty\dodoFLOWconnection} \def\dodoFLOWconnection[#1][#2]#3% {\ignorespaces} \def\doFLOWconnect {\connection} \def\doFLOWlocate {\location} \def\doFLOWexit[#1]#2% {\setgvalue{#1FLOWexit}{#2}\ignorespaces} \def\startFLOWchart {\bgroup \let\stopFLOWchart\egroup \obeylines % lelijk, buffers nog eens fatsoeneren \dodoubleempty\dostartFLOWchart} \def\dostartFLOWchart[#1][#2]% {\preparenextFLOWchart{#1}{#2}% \dostartbuffer[\FLOWbufferprefix\nofFLOWcharts][startFLOWchart][stopFLOWchart]} \def\defineFLOWchart% {\dodoubleempty\dodefineFLOWchart} \long\def\dodefineFLOWchart[#1][#2]#3% {\preparenextFLOWchart{#1}{#2}% \setbuffer[\FLOWbufferprefix\nofFLOWcharts]#3\endbuffer} \def\preparenextFLOWchart#1#2% {\doglobal\increment\nofFLOWcharts \flowchart{#1}% \setxvalue{\@FLOW@-#1}{\noexpand\dohandleflowchart[\nofFLOWcharts][#2]}} \def\setupFLOWcharts{\dodoubleargument\getparameters[\@@FLOW]} \def\setupFLOWlines {\dodoubleargument\getparameters[\@@FLOL]} \def\setupFLOWshapes{\dodoubleargument\getparameters[\@@FLOS]} \def\setupFLOWfocus {\dodoubleargument\getparameters[\@@FLOF]} \def\setupFLOWsets {\dodoubleargument\getparameters[\@@FLOX]} \setupFLOWcharts [\c!option=, \c!bodyfont=, \c!dot=, % private option \c!width=12\bodyfontsize, \c!height=7\bodyfontsize, \c!maxwidth=, \c!maxheight=, \c!offset=\v!standard, % == auto offset \c!dx=2\bodyfontsize, \c!dy=2\bodyfontsize, \c!nx=0, % 1, \c!ny=0, % 1, \c!x=1, \c!y=1, \c!autofocus=, \c!focus=, \c!background=, % \v!color, \c!backgroundcolor=\s!white, \c!rulethickness=\linewidth, \c!frame=\v!off, \c!framecolor=] \setupFLOWlines [\c!corner=\v!round, \c!arrow=\v!yes, \c!dash=\v!no, \c!radius=.375\bodyfontsize, % 2.5\c!rulethickness \c!color=FLOWlinecolor, \c!rulethickness=.15\bodyfontsize, % 2pt, \c!offset=\v!none] \setupFLOWshapes [\c!default=action, \c!framecolor=FLOWframecolor, \c!background=\v!color, \c!backgroundcolor=FLOWbackgroundcolor, \c!backgroundscreen=\@@rsscreen, \c!rulethickness=.15\bodyfontsize, % 2pt, \c!offset=.5\bodyfontsize] \setupFLOWfocus [\c!framecolor=FLOWfocuscolor, \c!background=\@@FLOSbackground, \c!backgroundcolor=\@@FLOSbackgroundcolor, \c!backgroundscreen=\@@FLOSbackgroundscreen, \c!rulethickness=\@@FLOSrulethickness, \c!offset=\@@FLOSoffset] \definecolor [FLOWfocuscolor] [s=.2] \definecolor [FLOWlinecolor] [s=.5] \definecolor [FLOWframecolor] [s=.7] \definecolor [FLOWbackgroundcolor] [s=.9] \newcounter\includeFLOWx \newcounter\includeFLOWy \def\includeFLOWchart {\dodoubleempty\doincludeFLOWchart} \def\doincludeFLOWchart[#1][#2]% {\pushmacro\includeFLOWx \pushmacro\includeFLOWy \getparameters[FLOWi][x=1,y=1,#2]% \increment(\includeFLOWx,0\FLOWix)\decrement\includeFLOWx \increment(\includeFLOWy,0\FLOWiy)\decrement\includeFLOWy \def\dodoincludeFLOWchart##1% {\doifdefined{\@FLOW@-##1} {\globalpushmacro\dohandleflowchart % was local \gdef\dohandleflowchart[####1][####2]% {\globalpopmacro\dohandleflowchart % was local \resetFLOWlocation \processFLOWbuffer{####1}}% \getvalue{\@FLOW@-##1}}}% \processcommalist[#1]\dodoincludeFLOWchart \popmacro\includeFLOWx \popmacro\includeFLOWy} \def\resetFLOWlocation {\globallet\lastFLOWx\!!zerocount \globallet\lastFLOWy\!!zerocount} \def\dosetFLOWlocation[#1#2]#3#4% {\processaction [#1#2] [ +=>\scratchcounter\numexpr#4+ 1+#3\relax, -=>\scratchcounter\numexpr#4- 1+#3\relax, +#2=>\scratchcounter\numexpr#4+#2+#3\relax, -#2=>\scratchcounter\numexpr#4-#2+#3\relax, \s!default=>\scratchcounter\numexpr#4 +#3\relax, \s!unknown=>\scratchcounter\numexpr0#1#2+#3\relax]% \xdef#4{\the\scratchcounter}} \def\setFLOWlocation#1,#2\end {\dosetFLOWlocation[#1\empty]\includeFLOWx\lastFLOWx \dosetFLOWlocation[#2\empty]\includeFLOWy\lastFLOWy \xdef\FLOWlocation{\lastFLOWx,\lastFLOWy}} \def\FLOWshapes {node, action, procedure, product, decision, archive, loop, wait, subprocedure, singledocument, multidocument, sub procedure, single document, multi document, up, down, left, right} \def\FLOWlines {up, down, left, right} \def\FLOWsetconnect#1% {\donefalse \let\cFLOWfrom\empty \let\cFLOWto\empty \let\zFLOWfrom\!!zerocount \let\zFLOWto\!!zerocount \handletokens#1\with\doFLOWsetconnect \ifx\cFLOWto\empty\let\cFLOWfrom\empty\fi} \def\doFLOWsetconnect#1% {\ifx #1p% \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi \else\ifx#1+% \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi \else\ifx#1n% \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi \else\ifx#1-% \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi \else\ifdone \edef\cFLOWto{\FLOWconnector#1}% \else \edef\cFLOWfrom{\FLOWconnector#1}% \donetrue \fi\fi\fi\fi\fi} \def\FLOWconnector#1% {\if#1bbottom\else\if#1ttop\else\if#1lleft\else\if#1rright\fi\fi\fi\fi} \newif\ifFLOWscaling \FLOWscalingtrue \def\@@FLOW@@offset{\@@FLOWoffset} \def\getFLOWchart {\dodoubleempty\dogetFLOWchart} \def\dogetFLOWchart[#1][#2]% {\doifundefinedelse{\@FLOW@-#1} {\writestatus{FLOW}{unknown chart #1}% \framed [\c!width=12\bodyfontsize,\c!height=8\bodyfontsize] {\tttf [chart #1]}} {\dodogetFLOWchart[#1][#2]}} \def\dodogetFLOWchart[#1][#2]% to be split a bit more {\vbox\bgroup \insidefloattrue \forgetall \dontcomplain % \offinterlineskip % we now explicitly use \nointerlineskip later on \def\dohandleflowchart[##1][##2]% {\def\currentFLOWnumber{##1}% \getparameters[\@@FLOW][##2]}% \getvalue{\@FLOW@-#1}% \getparameters[\@@FLOW][#2]% dubbelop ? \doifsomething{\@@FLOWautofocus} {\checkFLOWautofocus}% %\message{AUTOSHAPE 3: (\@@FLOWx,\@@FLOWy)->(\@@FLOWnx,\@@FLOWny)}\wait \global\let\FLOWwidth \@@FLOWnx \global\let\FLOWheight\@@FLOWny \let\startFLOWcell\startFLOWcellA \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber \ifcase\@@FLOWnx\relax \let\@@FLOWnx\FLOWwidth \fi \ifcase\@@FLOWny\relax \let\@@FLOWny\FLOWheight \fi \doifnothing{\@@FLOWmaxwidth\@@FLOWmaxheight}{\FLOWscalingfalse}% \ifFLOWscaling \doifnothing{\@@FLOWmaxwidth }{\let\@@FLOWmaxwidth \maxdimen}% \doifnothing{\@@FLOWmaxheight}{\let\@@FLOWmaxheight\maxdimen}% \scratchcounter\bodyfontpoints \doloop % NOG FONTSWITCH OM EX EN EM TE LATEN WERKEN {\ifnum\scratchcounter>1 % NU DIMENSIONS IN TERMS OF BODYFONTSIZE \bodyfontsize=\the\scratchcounter pt \dimen0=\@@FLOWmaxwidth \dimen2=\@@FLOWwidth \dimen4=\@@FLOWdx \advance\dimen2 2\dimen4 \dimen2=\@@FLOWnx\dimen2 \advance\dimen2 2\dimen4 \ifdim\dimen2>\dimen0 \advance\scratchcounter \minusone \else \dimen0=\@@FLOWmaxheight \dimen2=\@@FLOWheight \dimen4=\@@FLOWdy \advance\dimen2 2\dimen4 \dimen2=\@@FLOWny\dimen2 \advance\dimen2 2\dimen4 \ifdim\dimen2>\dimen0 \advance\scratchcounter \minusone \else \exitloop \fi \fi \else \exitloop \fi}% \expanded{\switchtobodyfont[\the\scratchcounter pt]}% \forgetall % \offinterlineskip % needed ? \else\ifx\@@FLOWbodyfont\empty\else \expanded{\switchtobodyfont[\@@FLOWbodyfont]}% \expanded ? \fi\fi \global\let\FLOWcells\empty \dimen0=\@@FLOWwidth \edef\FLOWshapewidth{\the\dimen0}% \dimen2=\@@FLOWdx \advance\dimen0 2\dimen2 \edef\FLOWgridwidth{\the\dimen0}% \dimen0=\@@FLOWheight \edef\FLOWshapeheight{\the\dimen0}% \dimen2=\@@FLOWdy \advance\dimen0 2\dimen2 \edef\FLOWgridheight{\the\dimen0}% \scratchdimen=\@@FLOSrulethickness \edef\@@FLOSrulethickness{\the\scratchdimen}% \scratchdimen=\@@FLOFrulethickness \edef\@@FLOFrulethickness{\the\scratchdimen}% \scratchdimen=\@@FLOLrulethickness \edef\@@FLOLrulethickness{\the\scratchdimen}% \ifdim\@@FLOLradius<2.5\scratchdimen \scratchdimen=2.5\scratchdimen \edef\@@FLOLradius{\the\scratchdimen}% \ifdim\@@FLOLradius>\@@FLOWdx \scratchdimen=\@@FLOWdx \edef\@@FLOLradius{\the\scratchdimen}% \fi \ifdim\@@FLOLradius>\@@FLOWdy \scratchdimen=\@@FLOWdy \edef\@@FLOLradius{\the\scratchdimen}% \fi \else \scratchdimen=\@@FLOLradius \edef\@@FLOLradius{\the\scratchdimen}% \fi \processaction % magic 2.5 [\@@FLOWoffset] [ \v!none=>\scratchdimen=-2.5\scratchdimen, \v!overlay=>\scratchdimen=-2.5\scratchdimen, \v!standard=>\scratchdimen=\scratchdimen, \s!unknown=>\scratchdimen=\@@FLOWoffset, \s!default=>\scratchdimen=-2.5\scratchdimen]% \edef\@@FLOW@@offset{\the\scratchdimen}% \forgetall \offinterlineskip \resetMPdrawing \doglobal\newcounter\FLOWcomment \startMPdrawing if unknown context_char : input mp-char.mpii ; fi ; grid_width := \FLOWgridwidth ; grid_height := \FLOWgridheight ; shape_width := \FLOWshapewidth ; shape_height := \FLOWshapeheight ; connection_line_width := \@@FLOLrulethickness ; connection_smooth_size := \@@FLOLradius ; connection_arrow_size := \@@FLOLradius ; connection_dash_size := \@@FLOLradius ; currentpicture := nullpicture ; begin_chart(0,\FLOWwidth,\FLOWheight); reverse_y := true ; chart_offset := \@@FLOW@@offset ; \stopMPdrawing \doifelsenothing\@@FLOWbackgroundcolor {\startMPdrawing chart_background_color := white ; \stopMPdrawing} {\startMPdrawing chart_background_color := \MPcolor{\@@FLOWbackgroundcolor} ; \stopMPdrawing}% \doif\@@FLOWoption\v!test {\startMPdrawing show_con_points := true ; show_mid_points := true ; show_all_points := true ; \stopMPdrawing}% \processaction % private [\@@FLOWdot] [ \v!yes=>\startMPdrawing show_con_points := true ; show_mid_points := true ; show_all_points := true ; \stopMPdrawing, \s!unknown=>\startMPdrawing show_\@@FLOWdot_points := true ; \stopMPdrawing]% \doglobal\newcounter\FLOWcomment \let\startFLOWcell\startFLOWcellB \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber \doglobal\newcounter\FLOWcomment \let\startFLOWcell\startFLOWcellC \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber \startMPdrawing clip_chart(\@@FLOWx,\@@FLOWy,\@@FLOWnx,\@@FLOWny) ; end_chart ; \stopMPdrawing \MPdrawingdonetrue \setbox0\hbox {\MPstaticgraphictrue \MPshiftdrawingfalse \getMPdrawing}% \def\MPmessage##1% {\writestatus{MP charts}{##1}}% \def\MPposition##1##2##3% {\setvalue{\@@MPx##1}{##2}\setvalue{\@@MPy##1}{##3}}% \def\MPclippath##1##2##3##4% {\def\clipMPllx{##1bp}\def\clipMPlly{##2bp}% \def\clipMPurx{##3bp}\def\clipMPury{##4bp}}% \def\MPareapath##1##2##3##4% {\def\areaMPllx{##1bp}\def\areaMPlly{##2bp}% \def\areaMPurx{##3bp}\def\areaMPury{##4bp}}% \getMPdata \doglobal\newcounter\FLOWcomment \let\startFLOWcell\startFLOWcellD \setbox2\vbox to \ht0 {\forgetall % \offinterlineskip \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber\vss}% \setbox2\hbox {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box2}% \wd2\wd0\ht2\ht0\dp2\dp0 \let\startFLOWcell\startFLOWcellE \setbox4\vbox to \ht0 {\forgetall % \offinterlineskip \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber\vss}% \setbox4\hbox {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box4}% \wd4\wd0\ht4\ht0\dp4\dp0 \doifelse\@@FLOWoption\v!test {\setbox6\vbox {\forgetall \vskip\@@FLOW@@offset \hskip\@@FLOW@@offset \basegrid [\c!x=\@@FLOWx,\c!nx=\@@FLOWnx,\c!dx=\withoutpt\FLOWgridwidth, \c!y=\@@FLOWy,\c!ny=\@@FLOWny,\c!dy=\withoutpt\FLOWgridheight, \c!xstep=1,\c!ystep=1, \c!unit=pt,\c!location=\v!middle]}% \wd6\wd0\ht6\ht0\dp6\dp0 \setbox8\vbox {\forgetall \offinterlineskip \vskip\@@FLOW@@offset \dostepwiserecurse\@@FLOWy\@@FLOWny\plusone {\vbox to \FLOWgridheight {\vfill \hskip\@@FLOW@@offset \hbox {\dostepwiserecurse\@@FLOWx\@@FLOWnx\plusone {\hbox to \FLOWgridwidth {\hfill \framed [\c!framecolor=red, \c!width=\FLOWshapewidth, \c!height=\FLOWshapeheight] {}% \hfill}}} \vfill}}}% \wd8\wd0\ht8\ht0\dp8\dp0 \framed [\c!offset=\v!overlay,\c!framecolor=green] {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2\hskip-\wd6\box6\hskip-\wd8\box8}}} {\framed [\c!offset=\v!overlay, \c!frame=\@@FLOWframe, \c!rulethickness=\@@FLOWrulethickness, \c!framecolor=\@@FLOWframecolor, \c!background=\@@FLOWbackground, \c!backgroundcolor=\@@FLOWbackgroundcolor] {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2}}}% %\message{[\FLOWcells]}\wait \egroup} % Pass A \long\def\startFLOWcellA#1\stopFLOWcell% {\resetFLOWcell \ignorespaces#1\unskip \expandafter\getFLOWlocationA\FLOWlocation\end \ignorespaces} \def\getFLOWlocationA#1,#2\end {\ifnum0#1>\FLOWwidth \xdef\FLOWwidth {#1}\fi \ifnum0#2>\FLOWheight\xdef\FLOWheight{#2}\fi} % Pass B % % beware: the - after \@FLOC@ is needed since name can be % empty and we don't want to redefine \@FLOC@ itself by % mistake \long\def\startFLOWcellB#1\stopFLOWcell {\resetFLOWcell\ignorespaces#1\unskip \setxvalue{\@FLOC@-\FLOWname}{\FLOWlocation}% kost veel cs's \ifx\FLOWshape\empty \global\let\FLOWshape\@@FLOSdefault \fi \doifnot\FLOWshape{none} % {\v!none} {\ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWshapes} {\edef\FLOWshapetag{shape_\FLOWshape}% beter \expanded \@EA\setFLOWname\@EA\FLOWshapetag\@EA{\FLOWshapetag}} {\doifnumberelse\FLOWshape {\let\FLOWshapetag\FLOWshape} {\let\FLOWshapetag\empty}}% \ifx\FLOWshapetag\empty \else \ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWlines} {\chardef\FLOWstate0 } {\ExpandBothAfter\doifcommonelse{\FLOWcell,\FLOWfocus}{\@@FLOWfocus} {\chardef\FLOWstate1 } {\chardef\FLOWstate2 }}% \startMPdrawing begin_sub_chart ; \ifcase\FLOWstate shape_line_color := \MPcolor{\@@FLOLcolor} ; shape_fill_color := \MPcolor{\@@FLOLcolor} ; shape_line_width := \@@FLOLrulethickness ; \or shape_line_color := \MPcolor{\@@FLOFframecolor} ; shape_fill_color := \MPcolor{\@@FLOFbackgroundcolor} ; shape_line_width := \@@FLOFrulethickness ; \or shape_line_color := \MPcolor{\@@FLOSframecolor} ; shape_fill_color := \MPcolor{\@@FLOSbackgroundcolor} ; shape_line_width := \@@FLOSrulethickness ; \fi %\ifx\FLOWoverlay\empty % peepshape := false ; %\else % peepshape := true ; %\fi peepshape := \ifx\FLOWoverlay\empty false \else true \fi ; new_shape(\FLOWlocation,\FLOWshapetag) ; end_sub_chart ; \stopMPdrawing \fi}% \ignorespaces} % Pass C \long\def\startFLOWcellC#1\stopFLOWcell% {\resetFLOWcell \pushmacro\lastFLOWx \pushmacro\lastFLOWy \ignorespaces#1\unskip % makes sure that vars are set \popmacro\lastFLOWy \popmacro\lastFLOWx \let\connection\doFLOWconnectionC \ignorespaces#1\unskip} \def\FLOWorigin{0,0} \def\doFLOWdisplace[#1,#2,#3]% experiment {dsp_x := #1 ; dsp_y := #2 ;} \def\doFLOWconnectionC {\dodoubleempty\dodoFLOWconnectionC} \def\dodoFLOWconnectionC[#1][#2]#3% {\doglobal\increment\FLOWcomment \setFLOWname\otherFLOWname{name_#3}% \doifdefinedelse{\@FLOC@-\FLOWname} {\edef\FLOWfrom{\getvalue{\@FLOC@-\FLOWname}}} {\let \FLOWfrom \FLOWorigin}% \ifx\FLOWfrom\FLOWorigin \else \doifdefinedelse{\@FLOC@-\otherFLOWname} {\edef\FLOWto {\getvalue{\@FLOC@-\otherFLOWname}}} {\let \FLOWto \FLOWorigin}% \ifx\FLOWto\FLOWorigin \else \FLOWsetconnect{#1}% \ifx\cFLOWfrom\empty \else \doifelse\@@FLOLcorner\v!round {\startMPdrawing smooth := true ; \stopMPdrawing} {\startMPdrawing smooth := false ; \stopMPdrawing}% \doifelse\@@FLOLdash\v!yes {\startMPdrawing dashline := true ; \stopMPdrawing} {\startMPdrawing dashline := false ; \stopMPdrawing}% \doifelse\@@FLOLarrow\v!yes {\startMPdrawing arrowtip := true ; \stopMPdrawing} {\startMPdrawing arrowtip := false ; \stopMPdrawing}% \doifelse\@@FLOLoffset\v!none {\startMPdrawing touchshape := true ; \stopMPdrawing} {\startMPdrawing touchshape := false ; \stopMPdrawing}% %\doifsomething{#2} % {\startMPdrawing % \doFLOWdisplace[0#2,0,0]% % \stopMPdrawing}% \startMPdrawing \doFLOWdisplace[0#2,0,0]% connection_line_color := \MPcolor{\@@FLOLcolor} ; connection_line_width := \@@FLOLrulethickness ; connect_\cFLOWfrom_\cFLOWto (\FLOWfrom,\zFLOWfrom) (\FLOWto,\zFLOWto) ; \doFLOWdisplace[0,0,0]% \stopMPdrawing \fi \fi \fi \ignorespaces} % Pass D \long\def\startFLOWcellD#1\stopFLOWcell {\resetFLOWcell \pushmacro\lastFLOWx \pushmacro\lastFLOWy \ignorespaces#1\unskip % presets vars \popmacro\lastFLOWy \popmacro\lastFLOWx \let\doprocessFLOWcell\doprocessFLOWcellD \expandafter\doprocessFLOWcellD\FLOWlocation\end \let\connection\doFLOWconnectionD \let\comment\doFLOWcommentD \ignorespaces#1\unskip\ignorespaces} \def\doFLOWconnectionD {\dodoubleempty\dodoFLOWconnectionD} \def\dodoFLOWconnectionD[#1][#2]#3% {\doglobal\increment\FLOWcomment \ignorespaces} \def\doFLOWcommentD[#1]#2% {\bgroup \let\FLOW \middlebox \let\FLOWb \bottombox \let\FLOWbl\bottomleftbox \let\FLOWbr\bottomrightbox \let\FLOWt \topbox \let\FLOWtl\topleftbox \let\FLOWtr\toprightbox \let\FLOWl \leftbox \let\FLOWlt\lefttopbox \let\FLOWlb\leftbottombox \let\FLOWr \rightbox \let\FLOWrt\righttopbox \let\FLOWrb\rightbottombox \let\FLOWc \middlebox %\ifdefined{FLOW#1}% \ifcase0\getvalue{\@@MPx\FLOWcomment}\getvalue{\@@MPy\FLOWcomment}\relax \else \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp<\areaMPllx\relax\else \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp>\areaMPurx\relax\else \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp<\areaMPlly\relax\else \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp>\areaMPury\relax\else \dimen0=\getvalue{\@@MPx\FLOWcomment}\s!bp \advance\dimen0 -\@@FLOW@@offset \advance\dimen0 -\clipMPllx \dimen2=\clipMPury \advance\dimen2 -\@@FLOW@@offset \advance\dimen2 -\getvalue{\@@MPy\FLOWcomment}\s!bp \setbox\scratchbox\hbox{\strut#2}% \boxoffset.5\bodyfontsize \setbox\scratchbox\hbox{\hskip\dimen0\lower\dimen2\getvalue{FLOW#1}{\box\scratchbox}}% \smashbox\scratchbox \box\scratchbox \boxoffset\zeropoint \nointerlineskip % really needed \fi \fi \fi \fi \fi %\fi \egroup \ignorespaces} % pass D \def\dophaseoneFLOWcellX#1#2% {\!!counta#1\relax \!!countb#2\relax \!!countc\@@FLOWx \!!countd\@@FLOWy \advance\!!countc \@@FLOWnx \advance\!!countd \@@FLOWny \advance\!!countc \minusone \advance\!!countd \minusone \ifnum\!!counta<\@@FLOWx\relax \donefalse \else\ifnum\!!counta>\!!countc \donefalse \else\ifnum\!!countb<\@@FLOWy\relax \donefalse \else\ifnum\!!countb>\!!countd \donefalse \else \donetrue \fi\fi\fi\fi} \def\dophasetwoFLOWcellX {\advance\!!counta -\@@FLOWx \advance\!!counta \plusone \advance\!!countb -\@@FLOWy \advance\!!countb \plusone \dimen0=\FLOWgridwidth \dimen0=\!!counta\dimen0 \advance\dimen0 -\FLOWgridwidth \dimen4=\FLOWgridwidth \advance\dimen4 -\FLOWshapewidth \advance\dimen0 .5\dimen4 \dimen2=\FLOWgridheight \dimen2=\!!countb\dimen2 \dimen4=\FLOWgridheight \advance\dimen4 -\FLOWshapeheight \advance\dimen2 -.5\dimen4 \edef\FLOWdx{\the\dimen0}% \edef\FLOWdy{\the\dimen2}} \def\positionFLOWzero% assumes \FLOWdx and \FLOWdy are set {\setbox0\hbox{\hskip\FLOWdx\lower\FLOWdy\box0}% \smashbox0\box0 \nointerlineskip} % new, needed since we somehow reset that \def\doFLOWtlabel#1#2#3% {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi \setbox0\hbox{\hskip\dimen2\raise\scratchdimen \hbox{\raise\dimen4\hbox{#1{\strut#3}}}}% \positionFLOWzero}% \def\doFLOWblabel#1#2#3% {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi \setbox0\hbox{\hskip\dimen2\raise-\scratchdimen \hbox{#1{\strut#3}}}% \positionFLOWzero}% \def\doFLOWllabel#1#2#3% {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi \setbox0\hbox{\hskip-\scratchdimen\raise\dimen6 \hbox{#1{\strut#3}}}% \positionFLOWzero}% \def\doFLOWrlabel#1#2#3% {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi \setbox0\hbox{\hskip\dimen0\hskip\scratchdimen \hbox{\raise\dimen6\hbox{#1{\strut#3}}}}% \positionFLOWzero} \def\doprocessFLOWcellD#1,#2\end {\dophaseoneFLOWcellX{#1}{#2}% \ifdone \dophasetwoFLOWcellX \doglobal\addtocommalist\FLOWcell\FLOWcells \def\FLOWx{#1}% \def\FLOWy{#2}% \directsetup{flowcell}% \setbox0\hbox {\ifx\FLOWalign\empty\else \setupframed [\c!align=\v!normal,\c!bottom=\vfill,\c!top=\vfill]% \@EA\processallactionsinset\@EA [\FLOWalign] [t=>{\setupframed[\c!bottom=\vfill,\c!top=]}, b=>{\setupframed[\c!bottom=,\c!top=\vfill]}, l=>{\setupframed[\c!align=\v!right]}, r=>{\setupframed[\c!align=\v!left]}, m=>{\setupframed[\c!align=\v!middle]}, c=>{\setupframed[\c!align=\v!middle]}]% \fi \doifelse\FLOWshape{none} % {\v!none} {\setupframed[\c!offset=\v!overlay]} {\setupframed[\c!offset=\@@FLOSoffset]}% \framed [\c!frame=\v!off,\c!background=flowcell, \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight] {\FLOWtext}}% \showFLOWhelp0 \ifx\FLOWdestination\empty\else \setbox0\hbox {\setupinteraction[\c!color=,\c!contrastcolor=]% \gotobox{\box0}[\FLOWdestination]}% \fi \positionFLOWzero \dimen0=\FLOWshapewidth \dimen2=.5\dimen0 \dimen4=\FLOWshapeheight\dimen6=.5\dimen4 \boxoffset.5\bodyfontsize \doFLOWtlabel \righttopbox0\tFLOWlabel \doFLOWblabel\rightbottombox0\bFLOWlabel \doFLOWllabel \lefttopbox0\lFLOWlabel \doFLOWrlabel \righttopbox0\rFLOWlabel \doFLOWtlabel \topbox0\tcFLOWlabel % for me only \doFLOWblabel \bottombox0\bcFLOWlabel % for me only \doFLOWllabel \leftbox0\lcFLOWlabel % for me only \doFLOWrlabel \rightbox0\rcFLOWlabel % for me only \ifnum#1=\@@FLOWx\relax \doFLOWllabel \leftbox1\lFLOWexit \fi \ifnum#1=\!!countc \doFLOWrlabel \rightbox1\rFLOWexit \fi \ifnum#2=\@@FLOWy\relax \doFLOWtlabel \topbox1\tFLOWexit \fi \ifnum#2=\!!countd \doFLOWblabel \bottombox1\bFLOWexit \fi \boxoffset\zeropoint \fi} % For Willy Egger: % % \startsetups flowcell % \definelayer % [flowcell] % [width=\FLOWshapewidth, % height=\FLOWshapeheight] % \setlayerframed % [flowcell] % [preset=rightbottom,offset=1ex] % [frame=off] % {\tx(\FLOWx,\FLOWy)} % \stopsetups % Pass E \long\def\startFLOWcellE#1\stopFLOWcell {\resetFLOWcell \ignorespaces#1\unskip \let\doprocessFLOWcell\doprocessFLOWcellE \expandafter\doprocessFLOWcell\FLOWlocation\end} \def\doprocessFLOWcellE#1,#2\end % redundant {\ifx\FLOWoverlay\empty \else \dophaseoneFLOWcellX{#1}{#2}% \ifdone \dophasetwoFLOWcellX \edef\FLOWdx{\the\dimen0}% \edef\FLOWdy{\the\dimen2}% \setbox0\hbox {\framed [%\c!frame=\v!off, \c!background={\@@FLOWbackground,\FLOWoverlay}, \c!backgroundcolor=\@@FLOSbackgroundcolor, \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight] {}}% \positionFLOWzero \fi \fi} % Pass F \def\checkFLOWautofocus {\def\@@FLOWminx{100}\let\@@FLOWminy\@@FLOWminx \def\@@FLOWmaxx {0}\let\@@FLOWmaxy\@@FLOWmaxx \def\@@FLOWabsx {0}\let\@@FLOWabsy\@@FLOWabsx \let\startFLOWcell\startFLOWcellF \resetFLOWlocation \processFLOWbuffer\currentFLOWnumber %\message{AUTOSHAPE 1: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}% \ifnum\@@FLOWabsx<\@@FLOWmaxx\let\@@FLOWmaxx\@@FLOWabsx\fi \ifnum\@@FLOWabsy<\@@FLOWmaxy\let\@@FLOWmaxy\@@FLOWabsy\fi %\message{AUTOSHAPE 2: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}% \donetrue \ifnum\@@FLOWminx=100 \donefalse\fi \ifnum\@@FLOWminy=100 \donefalse\fi \ifnum\@@FLOWmaxx=0 \donefalse\fi \ifnum\@@FLOWmaxy=0 \donefalse\fi \doFLOWcheckF\@@FLOWx\@@FLOWminx\@@FLOWmaxx\@@FLOWnx \doFLOWcheckF\@@FLOWy\@@FLOWminy\@@FLOWmaxy\@@FLOWny} \def\startFLOWcellF#1\stopFLOWcell% {\resetFLOWcell \ignorespaces#1\unskip \expandafter\doFLOWlocationF\FLOWlocation\end}% \def\doFLOWlocationF#1,#2\end% {\ifnum#1>\@@FLOWabsx\def\@@FLOWabsx{#1}\fi \ifnum#2>\@@FLOWabsy\def\@@FLOWabsy{#2}\fi \ExpandBothAfter\doifinset{\FLOWcell}{\@@FLOWautofocus} {\dodoFLOWlocationF{#1}<-\@@FLOWminx \dodoFLOWlocationF{#1}>+\@@FLOWmaxx \dodoFLOWlocationF{#2}<-\@@FLOWminy \dodoFLOWlocationF{#2}>+\@@FLOWmaxy}} \def\dodoFLOWlocationF#1#2#3#4% {\ifnum#1#2#4\relax \!!counta=#1\advance\!!counta #31\relax \edef#4{\ifnum\!!counta<1 1\else\the\!!counta\fi}% \fi} \def\doFLOWcheckF#1#2#3#4% {\ifdone \let#1=#2% \!!counta=#3% \advance\!!counta \plusone\advance\!!counta -#2\relax \ifnum\!!counta<1 \!!counta=1 \fi \edef#4{\the\!!counta}% \else \let#1\!!plusone \let#4\!!zerocount % no {1} \fi} % \useFLOWchart[name][parent][setting,setting][additional settings] % \useFLOWchart[name][parent][additional settings] \let\currentFLOWchart\empty \def\useFLOWchart {\doquadrupleempty\douseFLOWchart} \def\douseFLOWchart[#1][#2][#3][#4]% name parent sets mainsettings {\iffourthargument \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][#4,##1]}% \else \checkparameters[#3]% \ifparameters \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][][#3,##1]}% \else \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][##1]}% \fi \fi} \def\setgetFLOWchart[#1][#2][#3]% {\def\docommand##1{}% cell line focus ? \processcommalist[#2]\docommand \getFLOWchart[#1][#3]} \def\doFLOWchart[#1][#2]% {\hbox\bgroup\vbox\bgroup % vmode suppresses spaces \def\currentFLOWchart{#1}% \doifundefinedelse{\@FLOW@--#1} {\getFLOWchart[#1][#2]} {\getvalue{\@FLOW@--#1}[#2]}% \egroup\egroup} \def\FLOWchart% {\dodoubleempty\doFLOWchart} %D A hook into the help system. \def\showFLOWhelp#1% {\doifhelpinfo\FLOWhelp {\setbox#1=\hbox {\setbox\scratchbox=\hbox{\lower\@@FLOWdy\hbox {\helpbutton [\c!width=\wd0,\c!color=,\c!height=\@@FLOWdy,\c!frame=\v!no]% [\FLOWhelp]}}% \smashbox\scratchbox \setbox#1=\vbox {\forgetall\offinterlineskip\box#1\box\scratchbox}% \box#1}}} %D The next section is dedicated to splitting up charts. \def\getFLOWsize[#1]% {\bgroup\let\dodogetFLOWchart\dogetFLOWsize\FLOWchart[#1]\egroup} \def\dogetFLOWsize[#1][#2]% {\setbox\scratchbox=\vbox {\globallet\FLOWmaxwidth \!!zerocount \globallet\FLOWmaxheight\!!zerocount \def\getFLOWlocation##1,##2\end {\ifnum0##1>\FLOWmaxwidth \xdef\FLOWmaxwidth {##1}\fi \ifnum0##2>\FLOWmaxheight\xdef\FLOWmaxheight{##2}\fi}% \resetFLOWcell \long\def\startFLOWcell##1\stopFLOWcell {{##1\expandafter\getFLOWlocation\FLOWlocation\end}}% \def\dohandleflowchart[##1][##2]% {\resetFLOWlocation \processFLOWbuffer{##1}}% \getvalue{\@FLOW@-#1}}} \def\setupFLOWsplit% {\dodoubleargument\getparameters[\@@FLOT]} \setupFLOWsplit% [\c!nx=3,\c!ny=3, \c!dx=1,\c!dy=1, \c!command=, \c!marking=\v!on, \c!before=,\c!after=] \def\FLOWsplitx {1} \def\FLOWsplity {1} \def\FLOWsplitnx{1} \def\FLOWsplitny{1} \def\FLOWcharts {\dodoubleempty\doFLOWcharts} %D While splitting, the following variables are available: %D %D \starttyping %D \FLOWsplitnx \FLOWsplitny \FLOWsplitx \FLOWsplity %D \stoptyping \def\doFLOWcharts[#1][#2]% {\bgroup \getFLOWsize[#1]% \dodoFLOWcharts\relax \global\let\FLOWsplitnx\FLOWsplitx \global\let\FLOWsplitny\FLOWsplity \dodoFLOWcharts{\dododoFLOWcharts[#1][#2]}% \egroup} \def\dodoFLOWcharts#1% {\def\@@FLOTx{1}% \global\let\FLOWsplitx\@@FLOTx \doloop {\def\@@FLOTy{1}% \global\let\FLOWsplity\@@FLOTy \doloop {\bgroup \scratchcounter\FLOWmaxwidth \advance\scratchcounter -\@@FLOTx \advance\scratchcounter \plusone \ifnum\scratchcounter<\@@FLOTnx\edef\@@FLOTnx{\the\scratchcounter}\fi \scratchcounter\FLOWmaxheight \advance\scratchcounter -\@@FLOTy \advance\scratchcounter \plusone \ifnum\scratchcounter<\@@FLOTny\edef\@@FLOTny{\the\scratchcounter}\fi #1% does something with the float, or not \egroup \increment(\@@FLOTy,\@@FLOTny)% \ifnum\@@FLOTy>\FLOWmaxheight \exitloop \else \doglobal\increment\FLOWsplity \decrement(\@@FLOTy,\@@FLOTdy)% \fi}% \increment(\@@FLOTx,\@@FLOTnx)% \ifnum\@@FLOTx>\FLOWmaxwidth \exitloop \else \doglobal\increment\FLOWsplitx \decrement(\@@FLOTx,\@@FLOTdx)% \fi}} \def\dododoFLOWcharts[#1][#2]% {\bgroup \@@FLOTbefore \doifnot\@@FLOTmarking\v!on{\let\cuthbox\hbox}% \cuthbox {\@@FLOTcommand {\FLOWchart[#1][#2, \c!x=\@@FLOTx,\c!nx=\@@FLOTnx, \c!y=\@@FLOTy,\c!ny=\@@FLOTny]}}% \@@FLOTafter \egroup} %D An example of splitting is given below: %D %D \starttyping %D \setupFLOWsplit %D [nx=5,ny=10, %D dx=0,dy=0, %D before=, %D after=\page] %D %D \FLOWcharts[mybigflow] %D \stoptyping %D %D Or, one can say: %D %D \starttyping %D \splitfloat %D {\placefigure{What a big flowchart this is!}} %D {\FLOWcharts[mybigflow]} %D \stoptyping %D \macros %D {typeFLOWchart} %D %D For documentation purposes the following macro is %D provided. Watch the use of the first and last line hooks, %D which is needed because the start and stop commands are %D not part of the buffer. \def\typeFLOWchart[#1]% {\bgroup \def\dohandleflowchart[##1][##2]{\typeFLOWbuffer{##1}}% \defconvertedargument\firstverbatimfileline{\startFLOWchart[#1]}% \defconvertedargument\lastverbatimfileline {\stopFLOWchart}% \getvalue{\@FLOW@-#1} \egroup} %D New: %D %D \starttyping %D \setupFLOWcharts[command=\Whow] %D %D \startFLOWset[convert-en] % [tag][convert-en] %D \subFLOWchart[a][x=1,y=1,nx=3,ny=3] %D \subFLOWchart[b][x=1,y=2,nx=3,ny=3] %D \subFLOWchart[c][x=2,y=1,nx=3,ny=3] %D \stopFLOWset %D %D \def\Whow#1% %D {\ifnum\currentFLOWset=1 \framed{Some Chart}\fi} %D %D \FLOWset[convert-en] % [tag] %D %D \def\Whow#1% %D {\setuphead[state=high] %D \startstandardmakeup %D \centerbox{#1} %D \stopstandardmakeup} %D %D \FLOWset[convert-en] % [tag] %D \stoptyping \def\startFLOWset {\dodoubleempty\dostartFLOWset} \def\dostartFLOWset[#1][#2]#3\stopFLOWset % tag name data {\ifsecondargument \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#2}{#3}}% \else \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#1}{#3}}% \fi} \long\def\dohandleFLOWset#1#2#3% tag name data {\bgroup \def\subFLOWchart {\dodoubleempty\dosubFLOWchart}% \def\dosubFLOWchart[##1][##2]% subtag settings {\ifsecondargument \dodohandleFLOWset{#1}{##1}{#2}{##2}% \else \subFLOWchart[][##1]% \fi}% #3% \egroup} \def\dodohandleFLOWset#1#2#3#4% tag subtag name settings {\increment\currentFLOWset \bgroup \@@FLOXcommand {\ifnum\currentFLOWset=1 \pagereference[#1]\fi \doifsomething{#2} {\setupreferencing[\c!prefix=]% \pagereference[#1:#2]% -:#1:#2 \setupreferencing[\c!prefix=#1:#2]}% \FLOWchart[#3][#4]}% \egroup} \def\FLOWset[#1]% {\newcounter\currentFLOWset \doifdefinedelse{\@FLOX@#1} {\getvalue{\@FLOX@#1}} {\dodohandleFLOWset{#1}{}{#1}{}}} \newcounter\currentFLOWset \setupFLOWsets [\c!command=] %D This will be an option: % \def\startFLOWchart% % {\dodoubleempty\dostartFLOWchart} % % \long\def\dostartFLOWchart[#1][#2]#3\stopFLOWchart % {\preparenextFLOWchart{#1}{#2}% % \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}} % % \long\def\dodefineFLOWchart[#1][#2]#3% % {\preparenextFLOWchart{#1}{#2}% % \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}} % % \def\processFLOWbuffer#1{\getvalue{\FLOWbufferprefix#1}} % \def\typeFLOWbuffer #1{[Sorry, no verbatim chart #1 available.]} %D The \XML\ interface: \startXMLdefinitions flowchart \defineXMLargument [flowchartdefinition] {\defineFLOWchart[\XMLpar{flowchartdefinition}{identifier}{unknown}]} \defineXMLpickup [flowcell] {\startFLOWcell \defineXMLargument[name]{\unspaceafter\name}% \defineXMLargument[shape]{\unspaceafter\shape}% \defineXMLnestedargument[text]{\text}} {\stopFLOWcell} \defineXMLenvironment [location] % global unspace/store {\bgroup\defineXMLpush[x]\defineXMLpush[y]} {\XMLunspace{x}\XMLunspace{y}% \expanded{\egroup\noexpand\location{\XMLpop{x},\XMLpop{y}}}} \defineXMLenvironment [connection] {\bgroup\defineXMLpush[type]\defineXMLpush[name]}% {\XMLunspace{type}\XMLunspace{name}% \expanded{\egroup\noexpand\connection[\XMLpop{type}]{\XMLpop{name}}}} \defineXMLsingular [flowchart] {\expanded{\FLOWchart[\XMLpar{flowchart}{identifier}{unknown}]}} \defineXMLdirective [flowchart] [shapes] \setupFLOWshapes \defineXMLdirective [flowchart] [lines] \setupFLOWlines \stopXMLdefinitions \protect \endinput