grph-fig.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=grph-fig,
%D        version=2006.08.26, % overhaul of 1997.03.31
%D          title=\CONTEXT\ Graphic Macros,
%D       subtitle=Figure Inclusion,
%D         author=Hans Hagen,
%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.

\writestatus{loading}{ConTeXt Graphic Macros / Figure Handling}

\unprotect

\def\setupexternalfigures
  {\dosingleempty\dosetupexternalfigures}

\def\dosetupexternalfigures[#1]%
  {\getparameters[\??ef][#1]%  local settings
   \getparameters[\??ex][#1]% global settings
   \setfigurepathlist} % the path may be used elsewhere too (as in x-res-04)

\presetlocalframed[\??ef]

\newconditional\externalfigurelevel % true=background false=normal
\newconditional\externalfigureflush % true=place false=ignore

\setfalse\externalfigurelevel
\settrue \externalfigureflush

\def\doplaceexternalfigure[#1][#2][#3][#4][#5]%
  {\doifsomething{#2}% catches \defineexternalfigure dummies
     {\doifundefinedelse{\??ef\??ef#2}
        {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]}
        {\doifelse{#1}{#2}
           {\dodoplaceexternalfigure[#1][#2][#3][#4][#5]}
           {\getvalue{\??ef\??ef#2}[#5]}}}}

\def\dodoplaceexternalfigure[#1][#2][#3][#4][#5]%
  {\bgroup
   \pushmacro\textunderscore
   \edef\textunderscore{\string_}% brrr, temp hack, still needed?
   \calculateexternalfigure      [][#1][#2][#3][#4][#5]% [] is dummy dwcomp
   \calculateexternalscreenfigure[][#1][#2][#3][#4][#5]% [] is dummy dwcomp
   \popmacro\textunderscore
   \box\foundexternalfigure
   \egroup}

\def\externalfigurereplacement#1#2#3%
  {\setupcolors
     [\c!state=\v!local]%
   \expanded{\localframed
     [\??ef]
     [\c!width=\figurewidth,
      \c!height=\figureheight,
      \c!background=\v!screen,
      \c!backgroundscreen=.8,
      \c!frame=\@@efframe]}%
     {\tt\tfxx \nohyphens
        name:  \expanded{\verbatimstring{#1}}\\%
        file:  \expanded{\verbatimstring{#2}}\\%
        state: \expanded{\verbatimstring{#3}}}}

\def\externalfigureplaceholder#1#2#3%
  {\localframed
     [\??ef]
     [\c!width=#2,
      \c!height=#3,
      \c!frame=\v!on]%
     {\tt\tfxx \nohyphens
        name:  \expanded{\verbatimstring{#1}}\\%
        state: \expanded{\verbatimstring{placeholder}}}}

% new: more convenient/efficient than
%
%   \use..[a][a][setting] \externalfigure[b][a]
%
% is equivalent to:
%
%   \def..[a][setting]    \externalfigure[b][a]
%
% see x-res modules for usage:
%
% \defineexternalfigure[name][settings]

\def\defineexternalfigure
  {\dodoubleargument\dodefineexternalfigure}

\def\dodefineexternalfigure[#1][#2]%
  {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][][][#2]}}

\def\getexternalfigure#1% efef has 4 args already and take an 5th
  {\wait} % OBSOLETE

% \useexternalfigure[alpha][koe]
% \useexternalfigure[beta] [koe]       [breedte=1cm]
% \useexternalfigure[gamma][koe][alpha]
% \useexternalfigure[delta][koe][alpha][breedte=2cm]
%
% volle breedte: \externalfigure[koe]                 \par
% 3cm breed:     \externalfigure[koe]  [breedte=3cm]  \par
% volle breedte: \externalfigure[alpha]               \par
% 1cm breed:     \externalfigure[beta]                \par
% volle breedte: \externalfigure[gamma]               \par
% 2cm breed:     \externalfigure[delta]               \par
% 4cm breed:     \externalfigure[beta] [breedte=4cm]  \par
% 5cm breed:     \externalfigure[gamma][breedte=5cm]  \par

% \defineexternalfigure[a][width=10cm]
% \defineexternalfigure[b][width=5cm]
% \externalfigure[cow][a]
% \externalfigure[cow][b][height=8cm]

% \useexternalfigure[x][cow][width=10cm,height=1cm]
% \externalfigure[x]
% \externalfigure[x][width=3cm]

\def\useexternalfigure
  {\doquadrupleempty\douseexternalfigure}

% [label] [filename]
% [label] [filename] [parent]
% [label] [filename] [parent] [settings]
% [label] [filename]          [settings]

\def\useexternalfigure
  {\doquadrupleempty\douseexternalfigure}

\def\douseexternalfigure[#1][#2][#3][#4]%
  {\doifelsenothing{#1}
     {\doifsomething{#2}
        {\doifassignmentelse{#3}
           {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][#3][#4]}}
           {\setvalue{\??ef\??ef#2}{\doplaceexternalfigure[#2][#2][][#4]}}}}
     {\doifelsenothing{#2}
        {\doifassignmentelse{#3}
           {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][][#3]}}
           {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#1][#3][#4]}}}
        {\doifassignmentelse{#3}
           {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][][#3]}}
           {\setvalue{\??ef\??ef#1}{\doplaceexternalfigure[#1][#2][#3][#4]}}}}}

\def\dosetefparameters#1#2#3% parent_id use_settings current_settings
  {\doifelsenothing{#1} % inherit from parent
     {\getparameters[\??ef][#2,#3]}
     {\doifdefinedelse{\??ef\??ef#1}
        {\pushmacro\doplaceexternalfigure
         \def\doplaceexternalfigure[##1][##2][##3][##4]{\getparameters[\??ef][##4,#2,#3]}%
         \getvalue{\??ef\??ef#1}%
         \popmacro\doplaceexternalfigure}
        {\getparameters[\??ef][#2,#3]}}}

\unexpanded\def\externalfigure
  {\dotripleempty\doexternalfigure}

\def\doexternalfigure[#1][#2][#3]% [label][file][settings] | [file][settings] | [file][parent][settings]
  {\bgroup
   \doifelsenothing{#1}
     {\framed[\c!width=\defaultfigurewidth,\c!height=\defaultfigureheight]{external\\figure\\no name}}
     {\doifundefinedelse{\??ef\??ef#1}
        {\useexternalfigure[\s!dummy][#1][#2][#3]%
         \getvalue{\??ef\??ef\s!dummy}[]} % [] is dummy arg 5
        {\doifassignmentelse{#2}
           {\getvalue{\??ef\??ef#1}[#2]}%
           {\getvalue{\??ef\??ef#1}[#3]}}}%
   \globallet\currentresourcecomment\empty
   \egroup}

\long\def\resourcecomment#1%
  {\long\gdef\currentresourcecomment{#1}}

\long\def\startresourcecomment#1\stopresourcecomment
  {\long\gdef\currentresourcecomment{#1}}

\let\currentresourcecomment\empty

\def\showexternalfigures % maybe run time command is better, but no core-run, unless figs-run ...
  {%\writestatus\m!systems{for \string\showexternalfigures\space see \truefilename{x-res-20}.tex}
   \usemodule[res-20]\showexternalfigures} % so for the moment we do it this way

\def\overlayfigure#1%
  {\externalfigure[#1][\c!width=\overlaywidth,\c!height=\overlayheight]}

%D Still undocumented! No one uses it I think, better be done with layers.

\newcount\efreference
\newdimen\efxsteps
\newdimen\efysteps

\def\calculateefsteps
  {\ifnum0\@@exxmax=\zerocount
     \ifnum0\@@exymax=\zerocount
       \def\@@exymax{24}%
     \fi
     \efysteps\figureheight \divide\efysteps \@@exymax
     \efxsteps\efysteps
     \dimen0=\figurewidth
     \advance\dimen0 \efysteps
     \divide \dimen0 \efysteps
     \edef\@@exxmax{\number\dimen0}%
   \else
     \efxsteps\figurewidth  \divide\efxsteps \@@exxmax
     \efysteps\figureheight \divide\efysteps \@@exymax
   \fi}

\def\efcomment#1(#2,#3)#4(#5,#6)%    {kader}(x,y)(h,b)[...]{tekst}
  {\def\complexefdocomment[##1]##2%
     {\position(#2,#3)%
        {\setnostrut
         \framed
           [\c!width=#5\efxsteps,
            \c!height=#6\exysteps,
            \c!offset=\v!none,
            \c!frame=#1,
            ##1]%
           {##2}}}%
   \complexorsimpleempty\efdocomment}

\def\efnocomment(#1,#2)#3(#4,#5)%    (x,y)(h,b)[...]{tekst}
  {\def\complexefdonocomment[##1]##2{}%
   \complexorsimpleempty\efdonocomment}

\def\efdomarker(#1,#2)#3#4%    (h,b){kader}{tekst}
  {\framed
     [\c!width=#1\efxsteps,
      \c!height=#2\efysteps,
      \c!offset=\v!none,
      \c!frame=#3]%
     {#4}}

\def\effigure#1%
  {\position(0,0){\getvalue{#1}}}

\def\efdoarea(#1,#2)#3#4%    (h,b){kader}{tekst}
  {\bgroup
   \setnostrut
   \framed
     [\c!width=#1\efxsteps,
      \c!height=#2\efysteps,
      \c!offset=\!!zeropoint,
      \c!frame=#3]
     {#4}%
   \egroup}

\def\efgoto(#1,#2)#3[#4]%    (h,b)kader[ref]
  {\setbox0=\vbox{\efdoarea(#1,#2)#3{}}%
   \gotobox{\copy0}[#4]}

\def\efmark(#1,#2)#3(#4,#5)#6[#7]%
  {\advance\efreference \plusone
   \position(#1,#2)
     {\hbox{\the\efreference}}%
   \position(#1,#2)
     {\gotosomeinternal\s!vwb{#7}\realfolio
        {\efdomarker(#4,#5)\v!on{\thisissomeinternal\s!vwa{#7}}}}}

\def\eftext#1(#2,#3)#4(#5,#6)#7[#8]%
  {\advance\efreference \plusone
   \hbox
     {\quad
      \thisissomeinternal\s!vwb{#8}%
      \gotosomeinternal  \s!vwa{#8}\realfolio
        {\hbox to 1.5em{\the\efreference\presetgoto\hfill}}%
      \quad#1 (#2,#3) (#5,#6) [#8]\hfill}%
   \endgraf}

\def\efthisis(#1,#2)#3[#4]%
  {\efdoarea(#1,#2){#3}{\pagereference[#4]}}

\newbox\colorbarbox

\def\makecolorbar[#1]%
  {\def\docommand##1%
     {\color[##1]
        {\blackrule
           [\c!width=2em,
            \c!height=1ex,
            \c!depth=\!!zeropoint]}%
      \endgraf}%
   \global\setbox\colorbarbox\vbox
     {\forgetall
      \processcommalist[#1]\docommand}%
   \global\setbox\colorbarbox\vbox
     {\hskip2em\box\colorbarbox}%
   \wd\colorbarbox\zeropoint}

\def\placestartfigure[#1][#2][#3]#4\placestopfigure[#5]%
  {\hbox
     {\setbox0\hbox
        {\useexternalfigure[\s!dummy][#2][#3,#5]%
         \externalfigure[\s!dummy]}%
      \calculateefsteps
      \startpositioning
        \def\referring(##1,##2)##3(##4,##5)##6[##7]%
          {\position(##1,##2){\efgoto(##4,##5){\@@exframes}[##7]}}%
        \def\marking(##1,##2)##3(##4,##5)##6[##7]%
          {\position(##1,##2){\efthisis(##4,##5){\@@exframes}[##7]}}%
        \def\remark{\efnocomment}%
        \def\colorbar##1[##2]{}%
        \position(0,0){\box0}%
        \linewidth\onepoint
        \setuppositioning
          [\c!unit=pt,
           \c!xscale=\withoutpt\the\efxsteps,
           \c!yscale=\withoutpt\the\efysteps,
           \c!factor=1]%
        \ignorespaces#4%
        \def\referring(##1,##2)##3(##4,##5)##6[##7]%
          {}%
        \let\marking\referring
        \def\remark{\efcomment\v!no}%
        \def\colorbar##1[##2]{\makecolorbar[##2]}%
        \ignorespaces#4%
      \stoppositioning
      \box\colorbarbox}}

\def\dodostartfigure[#1][#2][#3]#4\stopfigure
  {\doifelse\v!test\@@exoption
     {\teststartfigure[#1][#2][#3]#4\teststopfigure
      \let\@@exframes\v!on}
     {\let\@@exframes\v!off}%
   \setvalue{\??ef\??ef#1}%
     {\dosingleempty{\placestartfigure[#1][#2][#3]#4\placestopfigure}}%
   }% no longer \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}}

% De onderstaande macro mag niet zondermeer worden aangepast
% en is afgestemd op gebruik in de handleiding.

\def\teststartfigure[#1][#2][#3]#4\teststopfigure%
  {\begingroup
     \setbox0\hbox
       {\useexternalfigure[\s!dummy][#2][\c!wfactor=\v!max]%
        \externalfigure[\s!dummy]}%
     \def\referring{\efmark}%
     \def\marking{\efmark}%
     \def\remark{\efcomment\v!yes}%
     \def\colorbar##1[##2]{}%
     \efreference\zerocount
     \setbox0\vbox
       {\hsize240pt
        \startpositioning
          \calculateefsteps
          \position(0,0)
            {\box0}%
          \position(0,0)
            {\basegrid
               [\c!nx=\@@exxmax,
                \c!dx=\withoutpt\the\efxsteps,
                \c!ny=\@@exymax,
                \c!dy=\withoutpt\the\efysteps,
                \c!xstep=1,
                \c!ystep=1,
                \c!scale=1,
                \c!offset=\v!no,
                \c!unit=pt]}%
          \setuppositioning
            [\c!unit=pt,
             \c!xscale=\withoutpt\the\efxsteps,
             \c!yscale=\withoutpt\the\efysteps,
             \c!factor=1]%
          \linewidth\onepoint
          \ignorespaces#4\relax
        \stoppositioning
        \vfill}%
     \efreference\zerocount
     \def\referring{\eftext{$\rightarrow$}}%
     \def\marking{\eftext{$\leftarrow$}}%
     \def\remark{\efnocomment}%
     \def\colorbar##1[##2]{}%
     \setbox2\vbox
       {{\tfa\doifelsenothing{#1}{#2}{#1}}
        \blank
        \tfxx#4
        \vfilll}%
     \ifdim\ht0>\ht2
       \ht2\ht0
     \else
       \ht0\ht2
     \fi
     \hbox
       {\hskip3em
        \vtop{\vskip12pt\box0\vskip6pt}%
        \vtop{\vskip12pt\box2\vskip6pt}}%
   \endgroup}

\def\dodostartfigure[#1][#2][#3]#4\stopfigure
  {\doifelse\v!test\@@exoption
     {\teststartfigure[#1][#2][#3]#4\teststopfigure
      \let\@@exframe\v!on}
     {\let\@@exframe\v!off}%
   \setvalue{\??ef\??ef#1}%
     {\def\next{\placestartfigure[#1][#2][#3]#4\placestopfigure}%
      \dosingleempty\next}%
   }% no longer: \doifundefined{#1}{\setvalue{#1}{\getexternalfigure{#1}}}}

\long\def\dostartfigure#1%
  {\dotripleargument\dodostartfigure#1\stopfigure}

\def\startfigure
  {\grabuntil{\e!stop\v!figure}\dostartfigure}

%D defining sound tracks:
%D
%D \starttyping
%D \useexternalsoundtrack[label][file]
%D \stoptyping
%D
%D associated actions: StartSound StopSound PauseSound ResumeSound
%D
%D Todo: like external figures, also search on path,
%D although, they need to be present ar viewing time, so ...

\def\useexternalsoundtrack
  {\dodoubleargument\douseexternalsoundtrack}

\def\douseexternalsoundtrack[#1][#2]%
  {\setgvalue{\??sd:#1}{#2}}

\def\checksoundtrack#1%
  {\iflocation
     \doifdefined{\??sd:#1}{\doifvaluesomething{\??sd:#1}
       {\doinsertsoundtrack{\getvalue{\??sd:#1}}{#1}\@@sdoption
        % brr, \..empty not really needed and maybe even wrong;
        % also, not here but in driver
        % well, no: sounds need to be reinitialize each time (i.e., be on page), so no
        }}% \letgvalueempty{\??sd:#1}}}%
   \fi}

\setexecutecommandcheck {startsound} \checksoundtrack

\def\setupexternalsoundtracks
  {\dodoubleargument\getparameters[\??sd]}

\setupexternalsoundtracks
  [\c!option=]

%D NEW: used in styledesign manual

% \setbuffer[typeset-b]\endbuffer
% \setbuffer[typeset-a]\endbuffer
%
% todo:
%
% \appendtoks \setbuffer[typeset-b]\endbuffer\to \everystarttext
% \appendtoks \setbuffer[typeset-a]\endbuffer\to \everystarttext

\def\typesetbuffer
  {\dodoubleempty\dotypesetbuffer}

\newcounter\noftypesetbuffers % all loaded at the end

\defineexternalfigure
  [typeset]
  [\c!background=\v!color,
   \c!backgroundcolor=\s!white]

\def\dotypesetbuffer[#1][#2]% beware: this will mix up the mp graphics
  {\bgroup
   \def\TEXbufferfile##1{\bufferprefix##1.tex}%
   \expanded{\setbuffer[typeset]%
     \def\noexpand\bufferprefix{\ifprotectbuffers\jobname-\fi typeset-}}%
     \starttext
     \getbuffer[b,#1,a]%
     \stoptext
   \endbuffer
   \doglobal\increment\noftypesetbuffers
   % batch is needed
   \executesystemcommand{texmfstart texexec --batch --pdf --result=\bufferprefix typeset-\noftypesetbuffers\space \bufferprefix typeset.tex}%
   %\externalfigure[\bufferprefix typeset-\noftypesetbuffers.pdf][\c!object=\v!no,#2]%
   \externalfigure[\bufferprefix typeset-\noftypesetbuffers.pdf][#2]%
   \egroup}

% for me only (manuals and such)

\definesystemvariable{tz}

\def\definetypesetting{\dotripleempty\dodefinetypesetting}
\def\typesetfile      {\dotripleempty\dotypesetfile}

\def\dodefinetypesetting[#1][#2][#3]%
  {\doifsomething{#1}{\setvalue{\??tz#1}{\dodotypesetfile{#2}{#3}}}}

\def\dotypesetfile[#1][#2][#3]%
  {\executeifdefined{\??tz#1}\gobbletwoarguments{#2}{#3}}

\def\dodotypesetfile#1#2#3#4% args settings file settings
  {\doifmode{*\v!first}{\executesystemcommand{texmfstart texexec.pl --batch --pdf #1 #3}}%
   \doglobal\beforesplitstring#3\at.\to\typesetfilename
   \externalfigure[\typesetfilename.pdf][#2,#4]}

\setupexternalfigures
  [\c!option=,
   \c!object=\v!yes, % we only check for no
   \c!reset=\v!no,
   \c!maxwidth=\@@efwidth,
   \c!maxheight=\@@efheight,
   \c!bodyfont=\bodyfontsize,
   \c!directory=,
   \c!file=\f!utilityfilename.\f!figureextension,
   \c!radius=.5\bodyfontsize,
   \c!corner=\v!rectangular,
   \c!frame=\v!off,
   \c!background=, % new
   \c!splitcolor=\s!white,
   \c!conversion=,
   \c!prefix=,
   \c!cache=,
%  \c!grid=,
   \c!equalwidth=,
   \c!equalheight=,
   \c!location={\v!local,\v!global}]

\setupexternalfigures
  [\c!frames=\v!off,
   \c!ymax=24,
   \c!xmax=]

\useexternalfigure
  [buffer] [\jobname] [\c!type=\v!buffer,\c!object=\v!no]

\protect \endinput

% alternative for positioning

% \definelayer[figure][width=\overlaywidth,height=\overlayheight]
% \defineoverlay[figure][{\directsetup{figure}\tightlayer[figure]}]

% \setupcolors[state=start]

% \starttext

%     \startsetups figure
%         \setlayerframed[figure][preset=rightbottom,x=.25\layerwidth,y=.25\layerheight]{HERE}
%         \setlayerframed[figure][preset=leftbottom, x=.15\layerwidth,y=.35\layerheight]{THERE}
%     \stopsetups

%     \externalfigure[cow][background={foreground,figure},width=4cm,height=8cm]

%     \startsetups figure
%         \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{MORE}
%         \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE}
%     \stopsetups

%     \externalfigure[cow][background={foreground,figure},width=14cm,height=2cm]

%     \defineexternalfigure[whatever][background={foreground,figure}]

%     \startsetups figure
%         \setlayerframed[figure][preset=righttop,x=.25\layerwidth,y=.25\layerheight]{\red MORE}
%         \setlayerframed[figure][preset=middle,foregroundcolor=green]{EVEN MORE}
%     \stopsetups

%     \externalfigure[cow][whatever][width=14cm,height=4cm]

% \stoptext