page-txt.mkii / last modification: 2020-01-30 14:15
%D \module
%D   [       file=page-txt, % copied from main-001,
%D        version=1997.03.31,
%D          title=\CONTEXT\ Page Macros,
%D       subtitle=Texts,
%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.

% \setuplayouttext in manual

\writestatus{loading}{ConTeXt Page Macros / Texts}

\unprotect

\let\dodummypageskip\gobbleoneargument % obsolete

%D Interfacing between this and other modules is handled by
%D the following macros. The current state of a text line
%D (header, footer, etc.) is checked by:
%D
%D \starttyping
%D \resetlayouttextlines
%D \stoptyping
%D
%D The main text box is finished by the following macro:
%D
%D \starttyping
%D \getmainbox <box> <\vbox|\unvbox>
%D \stoptyping
%D
%D The text lines are collected with:
%D
%D \starttyping
%D \gettextboxes
%D \stoptyping
%D
%D It is possible to extens the default content of the text
%D areas by appending content to the following token list
%D registers:

\newtoks\toptextcontent     \newtoks\leftedgetextcontent
\newtoks\headertextcontent  \newtoks\leftmargintextcontent
\newtoks\footertextcontent  \newtoks\rightmargintextcontent
\newtoks\bottomtextcontent  \newtoks\rightedgetextcontent

\newtoks\texttextcontent

%D \macros
%D  {setuptop, setupheader, setuptext,
%D   setupfooter, setupbottom}
%D
%D The macros in this module sometimes look a bit more complicated
%D than needed, which is a direct result of the fact that their
%D ancestors are quite old and upward compatibility is a must.
%D
%D \showsetup{setuptop}
%D \showsetup{setupheader}
%D \showsetup{setuptext}
%D \showsetup{setupfooter}
%D \showsetup{setupbottom}

\def\setuplayouttext
  {\dotripleempty\dosetuplayouttext}

\def\dosetuplayouttext[#1][#2][#3]% beware, non global
  {\ifthirdargument
     \getparameters[\??tk#1#2][#3]%
   \else
    %\getparameters[\??tk#1\v!text][#2]%
     \edef\previoustextstate{\getvalue{\??tk#1\c!state}}%
     \getparameters[\??tk#1][#2]%
     \doifnotvalue{\??tk#1\c!state}\previoustextstate
       {%\checkcurrentlayout % no
        \edef\currenttextstate{\getvalue{\??tk#1\c!state}}%
        % speed optimization (calculating backgrounds takes time)
        \doifcommon{\previoustextstate,\currenttextstate}{\v!high,\v!none}
          {\calculatevsizes
           \recalculatebackgrounds
           \recalculatelogos}}%
   \fi}

\def\setuptop    {\dotripleempty\dosetuplayouttext[\v!top]}
\def\setupheader {\dotripleempty\dosetuplayouttext[\v!header]}
\def\setuptext   {\dotripleempty\dosetuplayouttext[\v!text]}
\def\setupfooter {\dotripleempty\dosetuplayouttext[\v!footer]}
\def\setupbottom {\dotripleempty\dosetuplayouttext[\v!bottom]}

%D \macros
%D  {noheaderandfooterlines,notopandbottomlines}
%D
%D Although not really needed, the following shortcuts
%D sometimes come in handy.
%D
%D \showsetup{noheaderandfooterlines}
%D \showsetup{notopandbottomlines}

\def\noheaderandfooterlines
  {\setupheader[\c!state=\v!empty]%
   \setupfooter[\c!state=\v!empty]}

\def\notopandbottomlines
  {\setuptop   [\c!state=\v!empty]%
   \setupbottom[\c!state=\v!empty]}

%D \macros
%D  {setuptoptexts, setupheadertexts, setuptexttexts,
%D   setupfootertexts, setupbottomtexts}
%D
%D The next macros take one or more arguments. The exact setup
%D depends on the number of arguments. Although not that
%D intuitive, the current scheme evolved out of the original.
%D When margin and edge texts as well as middle texts showed
%D up, the current odd|/|even scheme surfaced.
%D
%D \showsetup{setuptoptexts}
%D \showsetup{setupheadertexts}
%D \showsetup{setuptexttexts}
%D \showsetup{setupfootertexts}
%D \showsetup{setupbottomtexts}

\def\setuptoptexts    {\dosixtupleempty\dosetuptexts[\v!top]}
\def\setupheadertexts {\dosixtupleempty\dosetuptexts[\v!header]}
\def\setuptexttexts   {\dosixtupleempty\dosetuptexts[\v!text]}
\def\setupfootertexts {\dosixtupleempty\dosetuptexts[\v!footer ]}
\def\setupbottomtexts {\dosixtupleempty\dosetuptexts[\v!bottom]}

%D The left, right and center variables can also be set
%D directly using the previously discussed macros.

\def\dosetuptexts[#1][#2][#3][#4][#5][#6]%
  {\ifsixthargument
     \setvalue{\??tk#1#2\c!lefttext}%
       {\dodoubletexts{\??tk#1}{#2}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#3}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#6}}%
     \setvalue{\??tk#1#2\c!righttext}%
       {\dodoubletexts{\??tk#1}{#2}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#5}}%
   \else\iffifthargument
     \setvalue{\??tk#1\v!text\c!lefttext}%
       {\dodoubletexts{\??tk#1}\v!text
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#2}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#5}}%
     \setvalue{\??tk#1\v!text\c!righttext}%
       {\dodoubletexts{\??tk#1}\v!text
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}}%
   \else\iffourthargument
     \setvalue{\??tk#1#2\c!lefttext}%
       {\dodoubletexts{\??tk#1}{#2}
          {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}%
          {\c!leftstyle\c!leftcolor\c!leftwidth}{#3}}%
     \setvalue{\??tk#1#2\c!righttext}%
       {\dodoubletexts{\??tk#1}{#2}
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}}%
   \else\ifthirdargument
     \setvalue{\??tk#1\v!text\c!lefttext}%
       {\dodoubletexts{\??tk#1}\v!text
          {\c!leftstyle\c!leftcolor\c!leftwidth}{#2}%
          {\c!leftstyle\c!leftcolor\c!leftwidth}{#2}}%
     \setvalue{\??tk#1\v!text\c!righttext}%
       {\dodoubletexts{\??tk#1}\v!text
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}}%
   \else\ifsecondargument % new
     \letvalue{\??tk#1\v!text\c!lefttext }\empty
     \letvalue{\??tk#1\v!text\c!righttext}\empty
     \setvalue{\??tk#1\v!text\c!middletext }%
       {\dosingletexts{\??tk#1}\v!text\c!style\c!color\c!width{#2}}%
   \else
     \dosixtupleempty\dosetuptexts[#1][\v!text][][][][]%
     \dosixtupleempty\dosetuptexts[#1][\v!margin][][][][]%
     \dosixtupleempty\dosetuptexts[#1][\v!edge ][][][][]%
   \fi\fi\fi\fi\fi}

%D Left and right texts are swapped on odd and even pages, but
%D only when double sided typesetting is enabled.

\def\dodoubletexts#1#2#3#4#5#6%
  {\doifoddpageelse
     {\dosingletexts{#1}{#2}#3{#4}}  % #3 => provides three arguments
     {\dosingletexts{#1}{#2}#5{#6}}} % #5 => provides three arguments

%D The next macro will be cleaned up amd made less messy and
%D dependent.

\def\placetextlinestrut#1%
  {\doifvalue{#1\c!strut}\v!yes{\setstrut\strut}}

\def\dosingletexts#1#2#3#4#5#6%
  {\bgroup
   \defconvertedargument\ascii{#6}%
   \doifsomething\ascii
     {\doattributes{#1#2}#3#4%
        {\placetextlinestrut{#1}% here !
        %\doifdefinedelse{\??mk\ascii\c!coupling} % brrr
         \doifelsemarking\ascii
           {\dolimitatetexts{#1#2#5}{\getmarking[\ascii][\v!first]}}
           {\ConvertConstantAfter\doifelse\v!pagenumber{#6}
               \@@plaatspaginanummer
              {\ConvertConstantAfter\doifelse\v!date{#6}
                 {\currentdate}
                 {% #6{}{}{} -> {} needed for macros that look
                  % ahead, like \uniqueMPgraphic
                  \opeenregel\dolimitatetexts{#1#2#5}{#6{}{}{}}}}}}}%
  \egroup}

%D When specified, the texts are automatically limited in
%D length.

\def\dolimitatetexts#1#2%
  {\doifelsevaluenothing{#1}{#2}{\limitatetext{#2}{\getvalue{#1}}{\unknown}}}

%D The placement of text is hooked into the token lists
%D associated to the area at hand.

\appendtoks \placelayouttextline\v!top   \topheight    \to \toptextcontent
\appendtoks \placelayouttextline\v!header\headerheight \to \headertextcontent
\appendtoks \placelayouttextline\v!text  \textheight   \to \texttextcontent
\appendtoks \placelayouttextline\v!footer\footerheight \to \footertextcontent
\appendtoks \placelayouttextline\v!bottom\bottomheight \to \bottomtextcontent

%D Texts can be disabled, moved up and ignored, depending in
%D the \type {status} variable. This is handled by the next
%D couple of macros.

\def\settextlinestatus  #1{\edef\textlinestatus{\csname\??tk#1\c!state\endcsname}}
%def\resettextlinestatus#1{\letgvalue{\??tk#1\c!state}\v!normal}

\def\resettextlinestatus#1% postpone
  {\setgvalue{\??tk#1\s!reset}{\letgvalue{\??tk#1\c!state}\v!normal}}

\def\placelayouttextline#1% #2
  {\settextlinestatus{#1}%
   \csname\string\placelayouttextline
     \ifundefined{\string\placelayouttextline\textlinestatus}%
       \s!unknown
     \else
       \textlinestatus
     \fi
   \endcsname{#1}} % {#2}

\def\doifelselayouttextline#1% shown or not
  {\doifinsetelse{\getvalue{\??tk#1\c!state}}{\v!normal,\v!start}}

\def\doifelselayoutsomeline#1% present or not
  {\edef\!!stringa{\csname\??tk#1\c!state\endcsname}%
   \ifx\!!stringa\v!none
     \@EA\secondoftwoarguments
   \else\ifx\!!stringa\v!high
     \@EAEAEA\secondoftwoarguments
   \else
     \@EAEAEA\firstoftwoarguments
   \fi\fi}

% \doplacelayouttextline does the actual placement (when a non-zero height)

\newconditional\resyncaftertextline

\setvalue{\string\placelayouttextline\v!normal }{\doplacelayouttextline}
\setvalue{\string\placelayouttextline          }{\doplacelayouttextline}

\setvalue{\string\placelayouttextline\v!none}#1#2%
  {}

\setvalue{\string\placelayouttextline\v!high}#1#2%
  {\global\settrue\resyncaftertextline
   \resettextlinestatus{#1}}

\setvalue{\string\placelayouttextline\v!empty}#1#2%
  {\resettextlinestatus{#1}}

\setvalue{\string\placelayouttextline\v!start}#1#2%
  {\resettextlinestatus{#1}%
   \doplacelayouttextline{#1}{#2}}

\setvalue{\string\placelayouttextline\v!stop}#1#2%
  {}

\setvalue{\string\placelayouttextline\v!nomarking}#1#2%
  {\bgroup
   \resettextlinestatus{#1}%
   \let\dogetmarking\nogetmarking
   \doplacelayouttextline{#1}{#2}%
   \egroup}

\setvalue{\string\placelayouttextline\s!unknown}#1#2%
  {\global\settrue\resyncaftertextline
   \bgroup % new
   \resettextlinestatus{#1}%
   \getvalue{\??tk#1\textlinestatus}%
   \getvalue{\??tk#1\v!text  \textlinestatus}%
   \getvalue{\??tk#1\v!margin\textlinestatus}%
   \getvalue{\??tk#1\v!edge  \textlinestatus}%
   \doplacelayouttextline{#1}{#2}%
   \egroup}

%D The following macro has to be called after a page
%D is flushed.

\def\resetlayouttextline#1%
  {\getvalue {\??tk#1\s!reset}%
   \letgvalue{\??tk#1\s!reset}\relax}

\def\resetlayouttextlines
  {\resetlayouttextline\v!top
   \resetlayouttextline\v!header
   \resetlayouttextline\v!text
   \resetlayouttextline\v!footer
   \resetlayouttextline\v!bottom
   \ifconditional\resyncaftertextline
     \doglobal\calculatevsizes
     \recalculatebackgrounds
     \recalculatelogos
     \global\setfalse\resyncaftertextline
   \fi}

% \settext[header][text][middle][xxx][yyy]

\def\settextcontent
  {\doquintupleempty\dosettextcontent}

\def\dosettextcontent[#1][#2][#3][#4][#5]% header text middle text/text
  {\iffifthargument
     \setvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}%
       {\dodoubletexts{\??tk#1}{#2}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#5}}%
   \else\iffourthargument
     \setvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}%
       {\dodoubletexts{\??tk#1}{#2}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#4}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#4}}%
   \else\ifthirdargument
     \setvalue{\??tk#1#2\c!middletext}%
       {\dodoubletexts{\??tk#1}{#2}%
          {\c!leftstyle \c!leftcolor \c!leftwidth }{#3}%
          {\c!rightstyle\c!rightcolor\c!rightwidth}{#3}}%
   \fi\fi\fi}

\def\resettextcontent
  {\dotripleempty\doresettextcontent}

\def\doresettextcontent[#1][#2][#3]% header text middle
  {\ifthirdargument
     \letvalue{\??tk#1#2\executeifdefined{:\c!text:#3:}\c!middletext}\empty
   \else\ifsecondargument
     \letvalue{\??tk#1#2\c!lefttext  }\empty
     \letvalue{\??tk#1#2\c!middletext}\empty
     \letvalue{\??tk#1#2\c!righttext }\empty
   \fi\fi}

\let\settext  \settextcontent    % downward compatibility
\let\resettext\resettextcontent  % downward compatibility

\setvalue{:\c!middle:\c!text:}{\c!middletext}
\setvalue{:\c!left  :\c!text:}{\c!lefttext  }
\setvalue{:\c!right :\c!text:}{\c!righttext }

%D The next series of macros is not that easy to read,
%D because they hook into the main page building macros. By
%D using token list registers for the text content, we can
%D easily hook in other code, like menu generators.
%D
%D Beware: the token lists are always expanded, also when the
%D height of an area is zero. This is because reset actions can
%D be part of them.

\newbox\scratchpagebox

\def\gettextboxes
  {\setbox\scratchpagebox\vbox
     {\dontcomplain
      \calculatereducedvsizes
      \swapmargins
      \offinterlineskip
      \vskip\dimexpr-\topheight-\topdistance\relax
      \the\toptextcontent
      \vskip\dimexpr\topheight+\topdistance\relax
      \the\headertextcontent
      \vskip\dimexpr\headerheight+\headerdistance\relax
      \placepositionanchors
      \vskip-\textheight
      \the\texttextcontent
      \vskip\textheight
      \the\everyendoftextbody
      \vskip\footerdistance
      \the\footertextcontent
      \vskip\dimexpr\footerheight+\bottomdistance\relax
      \the\bottomtextcontent
      \vskip\bottomheight
      \vfilll}%
  \smashbox\scratchpagebox
  \box\scratchpagebox}

\def\getmainbox#1#2%
  {\setbox\scratchpagebox\vbox
     {\offinterlineskip  % na \paginaletter !
      \calculatereducedvsizes
      \calculatehsizes
      \swapmargins
      \vskip\dimexpr\headerheight+\headerdistance+\layoutparameter\c!textdistance\relax
      \hbox to \makeupwidth
        {\bgroup
           \swapmargins
           \goleftonpage
           \ifdim\leftedgewidth>\zeropoint
             \the\leftedgetextcontent
             \hskip\leftedgewidth
           \fi
           \hskip\leftedgedistance
           \ifdim\leftmarginwidth>\zeropoint
             \the\leftmargintextcontent
             \hskip\leftmarginwidth
           \fi
           \hskip\leftmargindistance
         \egroup
         \mkprocesspagecontents{#2}%
         \settextpagecontent\scratchpagebox{#1}{#2}%
         \setbox\scratchpagebox\vbox % can we avoid this extra box
           {\startlayoutcomponent{textbody}{text body}%
            \box\scratchpagebox
            \stoplayoutcomponent}%
         \addtextbackground\scratchpagebox
         \addtextgridlayer\scratchpagebox
         \localstarttextcolor % does not work in mkiv
         \box\scratchpagebox
         \localstoptextcolor  % so we have to change this
         \bgroup
           \hskip\rightmargindistance
           \ifdim\rightmarginwidth>\zeropoint
             \the\rightmargintextcontent
             \hskip\rightmarginwidth
           \fi
           \hskip\rightedgedistance
           \ifdim\rightedgewidth>\zeropoint
             \the\rightedgetextcontent
             \hskip\rightedgewidth
           \fi
         \egroup
         \hss}}%
   \smashbox\scratchpagebox
   \box\scratchpagebox}

%D The main text area has to be combined with some additional
%D (tracing) information.

% will be overloaded in page-lyr

\def\settextpagecontent#1#2#3% #2 and #3 will disappear
  {\setbox#1\hbox to \makeupwidth
     {\hss                        % so don't change this
      \vbox to \textheight
        {\offinterlineskip
         \freezetextwidth
         \hsize\textwidth      % local variant of \sethsize
         \boxmaxdepth\maxdepth
         \noindent                % content can be < \hsize
         \dopagecontents#2#3}%
      \hss}%
   \dp#1\zeropoint}

\definepalet
  [layout]
  [grid=red,
   page=green]

\def\addtextgridlayer#1% tzt run time
  {\ifcase\showgridstate\else % 1=bottom 2=top
     \setgridbox\scratchbox\makeupwidth\textheight
     \setbox#1\hbox
       {\ifcase\showgridstate\or\or\box#1\hskip-\makeupwidth\fi
        \bgroup % color
        \startlayoutcomponent{gridcolumns}{grid columns}%
        \incolortrue
        \ifcase\layoutcolumns\else
          \gray
          \hbox to \makeupwidth
            {\dorecurse\layoutcolumns
               {\hskip\layoutcolumnwidth
                \ifnum\recurselevel<\layoutcolumns
                  \vrule
                    \!!height\ht\scratchbox
                    \!!depth\dp\scratchbox
                    \!!width\layoutcolumndistance
                \fi}}%
          \hskip-\makeupwidth
        \fi
        \stoplayoutcomponent
        \startlayoutcomponent{gridlines}{grid lines}%
        \startcolor[layout:grid]\box\scratchbox\stopcolor
        \stoplayoutcomponent
        \egroup
        \ifcase\showgridstate\or\hskip-\makeupwidth\box#1\fi}%
   \fi}

%D The placement of a whole line is handled by the next two
%D macros. These are hooked into the general purpose token
%D list registers mentioned before.

\def\ignoredlinebreak{\unskip\space\ignorespaces}

\def\doplacelayouttextline#1#2%
  {\ifdim#2>\zeropoint\relax  % prevents pagenumbers when zero height
     \goleftonpage
     \hbox
       {\setbox\scratchpagebox\vbox to #2
          {%\forgetall
           \vsize#2\relax
           \normalbaselines
           \let\\\ignoredlinebreak
           \let\crlf\ignoredlinebreak
          %\getvalue{\??tk#1\v!text\c!before}%
           \getvalue{\??tk#1\c!before}%
           \doifbothsidesoverruled
             {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\gobbleoneargument\getvalue}
             {\dodoplacelayouttextline#1\c!lefttext \c!middletext\c!righttext\gobbleoneargument\getvalue}
             {\dodoplacelayouttextline#1\c!righttext\c!middletext\c!lefttext \getvalue\gobbleoneargument}%
          %\getvalue{\??tk#1\v!text\c!after}%
           \getvalue{\??tk#1\c!after}%
           \kern\zeropoint}% keep the \dp, beware of \vtops, never change this!
        \dp\scratchpagebox\zeropoint
        \box\scratchpagebox}%
     \vskip-#2\relax
   \fi}

\def\dodoplacelayouttextline#1#2#3#4#5#6% \hsize toegevoegd, \hss's niet meer wijzigen
  {\hbox
     {\ifdim\leftedgewidth>\zeropoint
        \dododoplacelayouttextline\leftedgewidth{#1}\v!edge
          {\hss\getvalue{\??tk#1\v!edge#2}}%
        \hskip\leftedgedistance
      \fi
      \ifdim\leftmarginwidth>\zeropoint
        \dododoplacelayouttextline\leftmarginwidth{#1}\v!margin
          {\hbox to \leftmarginwidth
             {\hss\getvalue{\??tk#1\v!margin#2}}%
           \hskip-\leftmarginwidth
           \hbox to \leftmarginwidth
             {\hss#5{\??tk#1\v!margin\c!margintext}}}%
        \hskip\leftmargindistance
      \fi
      \ifdim\makeupwidth>\zeropoint
        \dododoplacelayouttextline\makeupwidth{#1}\v!text
          {\hbox to \makeupwidth
             {\@@nmpre{#5{\??tk#1\v!text\c!marginedgetext}}%
              \getvalue{\??tk#1\v!text#2}\hss}%
           \hskip-\makeupwidth
           \hbox to \makeupwidth
             {\hss\getvalue{\??tk#1\v!text#3}\hss}%
           \hskip-\makeupwidth
           \hbox to \makeupwidth
             {\hss\getvalue{\??tk#1\v!text#4}%
              \@@nmpos{#6{\??tk#1\v!text\c!marginedgetext}}}}%
      \fi
      \ifdim\rightmarginwidth>\zeropoint
        \hskip\rightmargindistance
        \dododoplacelayouttextline\rightmarginwidth{#1}\v!margin
          {\hbox to \rightmarginwidth
             {\getvalue{\??tk#1\v!margin#4}\hss}%
           \hskip-\rightmarginwidth
           \hbox to \rightmarginwidth
             {#6{\??tk#1\v!margin\c!margintext}\hss}}%
      \fi
      \ifdim\rightedgewidth>\zeropoint
        \hskip\rightedgedistance
        \dododoplacelayouttextline\rightedgewidth{#1}\v!edge
          {\getvalue{\??tk#1\v!edge#4}\hss}%
      \fi}}

% \def\dododoplacelayouttextline#1#2#3#4%
%   {\vbox % to \vsize
%      {\hsize#1\relax
%       \getvalue{\??tk#2#3\c!voor}
%       \hbox to #1{#4}%
%       \getvalue{\??tk#2#3\c!na}}}

\def\dododoplacelayouttextline#1#2#3#4%
  {\vbox % to \vsize
     {\hsize#1\relax
      \getvalue{\??tk#2#3\c!before}%
      \startlayoutcomponent{t:#2:#3}{area #2 #3}%
        \hbox to #1{#4}%
      \stoplayoutcomponent
      \getvalue{\??tk#2#3\c!after}}}

%D Although it is far better to use backgrounds for this
%D purpose, one can add a rule in the following way. This
%D method makes the rules disappear in case of an empty text
%D line. Consider this a feature.
%D
%D \starttyping
%D \setupheadertexts[left][right]
%D
%D \setupheader[text][after=\hrule,style=bold]
%D
%D \starttext
%D   \input tufte \page
%D   \setupheader[state=empty]
%D   \input tufte \page
%D \stoptext
%D \stoptyping

%D The next twosome will be done differently (using an
%D existing auxiliary macro).

% \def\@@nmpre#1{\setbox0\hbox{#1}\ifdim\wd0=\zeropoint\else\unhbox0\tfskip\fi}
% \def\@@nmpos#1{\setbox0\hbox{#1}\ifdim\wd0=\zeropoint\else\tfskip\unhbox0\fi}

% cleaner

\def\@@nmpre#1{\doiftext{#1}{{#1}\tfskip}}
\def\@@nmpos#1{\doiftext{#1}{\tfskip{#1}}}

% newer

\def\@@nmprepos#1#2#3#4#5%
  {\doifelsenothing\@@nmwidth
     {\doiftext{#5}{#1{#5}#2}}
     {\doiftext{#5}{\hbox to \@@nmwidth{#3{#5}#4}}}}

\def\@@nmpre{\@@nmprepos\empty\tfskip\relax\hss}
\def\@@nmpos{\@@nmprepos\tfskip\empty\hss\relax}

%D This code will move to \type {page-flt.tex}.

\appendtoks
  \plaatsrechtermargeblok \hskip-\rightmarginwidth
\to \rightmargintextcontent

\appendtoks
  \plaatslinkermargeblok \hskip-\leftmarginwidth
\to \leftmargintextcontent

%D The next hook will later be used for keeping track of
%D positions, i.e.\ it will provide a proper (page
%D dependent) reference point.

\ifx\undefined\placepositionanchors
  \def\placepositionanchors{\vskip\textheight}
\fi

%D \macros
%D   {definetext}
%D
%D Some macros ago, we implemented the \type {status} option
%D \type {unknown}. This one is used to take care of
%D symbolic texts handlers.
%D
%D \showsetup{definetext}
%D
%D The next example demonstrates how we can use this
%D mechanism to provide page (event) dependent text lines.
%D
%D \starttyping
%D \definetext[chapter][footer][pagenumber]
%D \setuphead[chapter][header=high,footer=chapter]
%D \setupheadertexts[pagenumber]
%D \setupfootertexts[left][right]
%D \chapter{eerste} \dorecurse{20}{\input tufte \relax}
%D \chapter{tweede} \dorecurse{20}{\input tufte \relax}
%D \stoptyping

\def\definetext
  {\doseventupleempty\dodefinetext}

\def\dodefinetext[#1][#2][#3][#4][#5][#6][#7]%
  {\ifseventhargument
     \setvalue{\??tk#2#3#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5][#6][#7]}%
   \else\ifsixthargument
     \setvalue{\??tk  #2#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5][#6]}%
   \else\iffifthargument
     \setvalue{\??tk#2#3#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4][#5]}%
   \else\iffourthargument
     \setvalue{\??tk  #2#1}{\dosixtupleempty\dosetuptexts[#2][#3][#4]}%
   \else
     \setvalue{\??tk  #2#1}{\dosixtupleempty\dosetuptexts[#2][#3]}%
   \fi\fi\fi\fi}

%D The rest of this file is dedicated to setting up the
%D texts. This code is not that impressive.

\setupheadertexts [\v!text] [] []
\setupheadertexts [\v!margin] [] []
\setupheadertexts [\v!edge]  [] []

\setupfootertexts [\v!text] [] []
\setupfootertexts [\v!margin] [] []
\setupfootertexts [\v!edge]  [] []

\setuptexttexts   [\v!text] [] []
\setuptexttexts   [\v!margin] [] []
\setuptexttexts   [\v!edge]  [] []

\setupbottomtexts [\v!text] [] []
\setupbottomtexts [\v!margin] [] []
\setupbottomtexts [\v!edge]  [] []

\setuptoptexts    [\v!text] [] []
\setuptoptexts    [\v!margin] [] []
\setuptoptexts    [\v!edge]  [] []

% alternative
%
% \def\resetlayouttekst%
%   {\dodoubleempty\doresetlayouttekst}
%
% \def\doresetlayouttekst[#1][#2]%
%   {\ifsecondargument
%      \dodoresetlayouttekst[#1][#2]%
%    \else
%      \dodoresetlayouttekst[#1][\v!tekst]%
%    \fi}
%
% \def\dodoresetlayouttekst[#1][#2]%
%   {...}
%
% \def\docommand#1%
%   {\resetlayouttekst[#1][\v!tekst]%
%    \resetlayouttekst[#1][\v!marge]%
%    \resetlayouttekst[#1][\v!rand]}

%D We combine a lot of similar settings in a macro that
%D we will later dispose.

\def\dodocommand[#1][#2]%
  {\getparameters
     [\??tk#1#2]
     [%\c!state=\v!normal, % moved
      \c!before=,  % both global and local are used
      \c!after=,    % both global and local are used
      \c!strut=, % the local one, not (yet) used
      \c!style=\getvalue{\??tk#1\c!style},% hm, got lost
      \c!color=\getvalue{\??tk#1\c!color},  % hm, got lost
      \c!lefttext=,
      \c!middletext=,
      \c!righttext=,
      \c!marginedgetext=,
      \c!margintext=,
      \c!width=]%
   \inheritparameter[\??tk#1#2][\c!leftstyle  ][\c!style ]%
   \inheritparameter[\??tk#1#2][\c!rightstyle ][\c!style ]%
   \inheritparameter[\??tk#1#2][\c!leftcolor   ][\c!color  ]%
   \inheritparameter[\??tk#1#2][\c!rightcolor  ][\c!color  ]%
   \inheritparameter[\??tk#1#2][\c!leftwidth ][\c!width]%
   \inheritparameter[\??tk#1#2][\c!rightwidth][\c!width]}

\def\docommand#1%
  {\dodocommand[#1][\v!text]%
   \dodocommand[#1][\v!margin]%
   \dodocommand[#1][\v!edge]}

\docommand\v!top
\docommand\v!header
\docommand\v!footer
\docommand\v!text
\docommand\v!bottom

\let\docommand  \relax
\let\dodocommand\relax

%D While the header and footer lines are moved away from the
%D main text, the top and bottom lines are centered.

\setuptop   [\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]
\setupheader[\c!state=\v!normal,\c!before=,    \c!after=\vss,\c!strut=\v!yes]
\setuptext  [\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]
\setupfooter[\c!state=\v!normal,\c!before=\vss,\c!after=,    \c!strut=\v!yes]
\setupbottom[\c!state=\v!normal,\c!before=\vss,\c!after=\vss,\c!strut=]

\setuptop   [\c!style=,\c!color=]
\setupheader[\c!style=,\c!color=]
\setuptext  [\c!style=,\c!color=]
\setupfooter[\c!style=,\c!color=]
\setupbottom[\c!style=,\c!color=]

\protect \endinput