% macros=mkvi % macros=mkvi %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. \writestatus{loading}{ConTeXt Page Macros / Texts} \unprotect \newtoks\toptextcontent \newtoks\leftedgetextcontent \newtoks\headertextcontent \newtoks\leftmargintextcontent \newtoks\footertextcontent \newtoks\rightmargintextcontent \newtoks\bottomtextcontent \newtoks\rightedgetextcontent \newtoks\texttextcontent %D \macros %D {setuptop, setupheader, setuptext,setupfooter, setupbottom} %D %D The macros in this module sometimes look a bit more complicated than needed, %D which is a direct result of the fact that their ancestors are quite old and %D upward compatibility is a must. %D %D \showsetup{setuptop} %D \showsetup{setupheader} %D \showsetup{setuptext} %D \showsetup{setupfooter} %D \showsetup{setupbottom} \installcorenamespace{layouttexts} \installcorenamespace{layouttextsline} \installcorenamespace{layouttextsreset} \installcorenamespace{layouttextssynchronize} \installcorenamespace{layouttextstrut} \installcorenamespace{layouttextspecial} \installcorenamespace{layouttextcontent} \installcommandhandler \??layouttexts {layoutelement} \??layouttexts % \appendtoks % \resetlayoutelementparameter\c!lefttext % resolves better % \resetlayoutelementparameter\c!middletext % \resetlayoutelementparameter\c!righttext % \to \everydefinelayoutelement \definelayoutelement[\v!top ] \definelayoutelement[\v!header] \definelayoutelement[\v!text ] \definelayoutelement[\v!footer] \definelayoutelement[\v!bottom] \definelayoutelement[\v!top :\v!text] [\v!top ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!header:\v!text] [\v!header][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!text :\v!text] [\v!text ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!footer:\v!text] [\v!footer][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!bottom:\v!text] [\v!bottom][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!top :\v!margin][\v!top ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!header:\v!margin][\v!header][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!text :\v!margin][\v!text ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!footer:\v!margin][\v!footer][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!bottom:\v!margin][\v!bottom][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!top :\v!edge] [\v!top ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!header:\v!edge] [\v!header][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!text :\v!edge] [\v!text ][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!footer:\v!edge] [\v!footer][\c!lefttext=,\c!middletext=,\c!righttext=] \definelayoutelement[\v!bottom:\v!edge] [\v!bottom][\c!lefttext=,\c!middletext=,\c!righttext=] \permanent\tolerant\protected\def\setuplayouttext[#vertical]#spacer[#horizontal]#spacer[#S#settings]% {\ifnum\lastarguments>\plustwo \setuplayoutelement[#vertical:#horizontal][#settings]% \else \setuplayoutelement[#vertical][#horizontal]% \fi} \appendtoks \ifempty\currentlayoutelement\else \page_layouts_synchronize_element\currentlayoutelement % brr, can be vertical:horizontal \fi \to \everysetuplayoutelement \mutable\lettonothing\currenttextstate \mutable\lettonothing\previoustextstate \def\page_layouts_reset_element_status#vertical% {\gdefcsname\??layouttextsreset#vertical\endcsname{\page_layouts_set_element_status_normal#vertical}} \def\page_layouts_set_element_status_normal#vertical% {\gletcsname\namedlayoutelementhash#vertical\c!state\endcsname\v!normal \gletcsname\??layouttextsreset#vertical\endcsname\relax \page_layouts_synchronize_element{#vertical}} \def\page_layouts_synchronize_element#vertical% {\xdef\previoustextstate{\csname\??layouttextssynchronize#vertical\endcsname}% can be a let \cdef\currenttextstate {\namedlayoutelementparameter{#vertical}\c!state}% %\writestatus{>>}{[#vertical:\currenttextstate/\previoustextstate]}% \ifx\currenttextstate\previoustextstate \else \page_layouts_synchronize_element_indeed{#vertical}% \fi} \def\page_layouts_synchronize_element_indeed#vertical% {\ifx\currenttextstate \v!high \calculatevsizes\page_backgrounds_recalculate \orelse \ifx\previoustextstate\v!high \calculatevsizes\page_backgrounds_recalculate \orelse \ifx\currenttextstate \v!none \calculatevsizes\page_backgrounds_recalculate \orelse \ifx\previoustextstate\v!none \calculatevsizes\page_backgrounds_recalculate \fi \gletcsname\??layouttextssynchronize#vertical\endcsname\currenttextstate} \permanent\protected\def\setuptop {\setuplayouttext[\v!top ]} \permanent\protected\def\setupheader{\setuplayouttext[\v!header]} \permanent\protected\def\setuptext {\setuplayouttext[\v!text ]} \permanent\protected\def\setupfooter{\setuplayouttext[\v!footer]} \permanent\protected\def\setupbottom{\setuplayouttext[\v!bottom]} %D We inherit some settings: \setuplayoutelement [ \c!leftstyle=\layoutelementparameter\c!style, \c!middlestyle=\layoutelementparameter\c!style, \c!rightstyle=\layoutelementparameter\c!style, \c!leftcolor=\layoutelementparameter\c!color, \c!middlecolor=\layoutelementparameter\c!color, \c!rightcolor=\layoutelementparameter\c!color, \c!leftwidth=\layoutelementparameter\c!width, \c!middlewidth=\layoutelementparameter\c!width, \c!rightwidth=\layoutelementparameter\c!width] %D \macros %D {noheaderandfooterlines,notopandbottomlines} %D %D Although not really needed, the following shortcuts sometimes come in handy. %D %D \showsetup{noheaderandfooterlines} %D \showsetup{notopandbottomlines} \permanent\protected\def\noheaderandfooterlines {\setuplayoutelement[\v!header][\c!state=\v!empty]% \setuplayoutelement[\v!footer][\c!state=\v!empty]} \permanent\protected\def\notopandbottomlines {\setuplayoutelement[\v!top ][\c!state=\v!empty]% \setuplayoutelement[\v!bottom][\c!state=\v!empty]} %D \macros %D {setuptoptexts,setupheadertexts,setuptexttexts,setupfootertexts,setupbottomtexts} %D %D The next macros take one or more arguments. The exact setup depends on the number %D of arguments. Although not that intuitive, the current scheme evolved out of the %D original. When margin and edge texts as well as middle texts showed up, the %D current odd|/|even scheme surfaced. %D %D \showsetup{setuptoptexts} %D \showsetup{setupheadertexts} %D \showsetup{setuptexttexts} %D \showsetup{setupfootertexts} %D \showsetup{setupbottomtexts} %D %D Only the following have checking for pagenumber, date and mark built in, so when %D someone uses the key|/|value interface these things have to be set explicitly as %D part of the text. \permanent\protected\def\setuptoptexts {\setuptexts[\v!top ]} \permanent\protected\def\setupheadertexts{\setuptexts[\v!header]} \permanent\protected\def\setuptexttexts {\setuptexts[\v!text ]} \permanent\protected\def\setupfootertexts{\setuptexts[\v!footer]} \permanent\protected\def\setupbottomtexts{\setuptexts[\v!bottom]} \mutable\lettonothing\currentlayoutelementstate \permanent\tolerant\protected\def\setuptexts[#vertical]#spacer[#horizontal]#spacer[#S#a]#spacer[#S#b]#spacer[#S#c]#spacer[#S#d]% {\ifarguments % there is always one \or \cdef\currentlayoutelement{#vertical:\v!text}% \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!righttext \resetlayoutelementparameter\c!middletext \cdef\currentlayoutelement{#vertical:\v!margin}% \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!righttext \resetlayoutelementparameter\c!middletext \cdef\currentlayoutelement{#vertical:\v!edge}% \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!righttext \resetlayoutelementparameter\c!middletext \or \cdef\currentlayoutelement{#vertical:\v!text}% \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!righttext \setlayoutelementparameter \c!middletext{\page_layouts_process_element_single{#horizontal}}% \or \cdef\currentlayoutelement{#vertical:\v!text}% \setlayoutelementparameter\c!lefttext {\page_layouts_process_element_single{#horizontal}}% \setlayoutelementparameter\c!righttext{\page_layouts_process_element_single{#a}}% \or \cdef\currentlayoutelement{#vertical:#horizontal}% \setlayoutelementparameter\c!lefttext {\page_layouts_process_element_single{#a}}% \setlayoutelementparameter\c!righttext{\page_layouts_process_element_single{#b}}% \or \cdef\currentlayoutelement{#vertical:\v!text}% \setlayoutelementparameter\c!lefttext {\page_layouts_process_element_double{#horizontal}{#c}}% \setlayoutelementparameter\c!righttext{\page_layouts_process_element_double{#a}{#b}}% \or \cdef\currentlayoutelement{#vertical:#horizontal}% \setlayoutelementparameter\c!lefttext {\page_layouts_process_element_double{#a}{#d}}% \setlayoutelementparameter\c!righttext{\page_layouts_process_element_double{#b}{#c}}% \fi} %D Left and right texts are swapped on odd and even pages, but only when double %D sided typesetting is enabled. \defcsname\??layouttextstrut\v!yes\endcsname{\setstrut\strut} % maybe more variants \lettonothing\m_page_layouts_element_content \protected\def\page_layouts_process_element_single#content% {\edef\m_page_layouts_element_content{\detokenize{#content}}% so no \v!xxx \ifcsname\??layouttextspecial\m_page_layouts_element_content\endcsname \lastnamedcs \else \doifelsemarking\m_page_layouts_element_content {\getmarking[\m_page_layouts_element_content][\v!first]}% {#content}% \fi} \protected\def\page_layouts_process_element_double#first#second% {\doifelseoddpage {\page_layouts_process_element_single{#first}} {\page_layouts_process_element_single{#second}}} \protected\def\page_layouts_process_element_indeed#style#color#width% {\begingroup \lefttoright % new \uselayoutelementstyleandcolor#style#color% \begincsname\??layouttextstrut\layoutelementparameter\c!strut\endcsname \ignorecrlf \edef\p_width{\layoutelementparameter#width}% \ifempty\p_width\else \expandafter\page_layouts_process_element_limited \fi\p_text \endgroup} \def\page_layouts_process_element_limited#content% are the {}{}{} still needed? {\limitated left \p_width text {#content}% sentinel {\unknown}% \relax} \defcsname\??layouttextspecial\v!pagenumber\endcsname{\page_layouts_place_page_number} \defcsname\??layouttextspecial\v!date \endcsname{\currentdate} %D When specified, the texts are automatically limited in length. \appendtoks \page_layouts_place_text_line\v!top \topheight \to \toptextcontent \appendtoks \page_layouts_place_text_line\v!header\headerheight \to \headertextcontent \appendtoks \page_layouts_place_text_line\v!text \textheight \to \texttextcontent \appendtoks \page_layouts_place_text_line\v!footer\footerheight \to \footertextcontent \appendtoks \page_layouts_place_text_line\v!bottom\bottomheight \to \bottomtextcontent %D Texts can be disabled, moved up and ignored, depending in the \type {status} %D variable. This is handled by the next couple of macros. \newinteger\c_page_layouts_element_state_n \mutable\lettonothing\textlinestatus \def\page_layouts_set_element_status#vertical% {\c_page_layouts_element_state_n=0\namedlayoutelementparameter#vertical\c!n\relax \ifcase\c_page_layouts_element_state_n \edef\textlinestatus{\namedlayoutelementparameter#vertical\c!state}% \else \xdefcsname\namedlayoutelementhash#vertical\c!n\endcsname{\the\numexpr\c_page_layouts_element_state_n+\minusone}% \let\textlinestatus\v!stop \fi} \appendtoks \ifinset\v!header\floatspecification\xdefcsname\namedlayoutelementhash\v!header\c!n\endcsname{1}\fi \ifinset\v!footer\floatspecification\xdefcsname\namedlayoutelementhash\v!footer\c!n\endcsname{1}\fi \to \everybeforeflushedpagefloat \protected\def\page_layouts_place_text_line#vertical% {\page_layouts_set_element_status#vertical\relax \ifcsname\??layouttextsline\textlinestatus\endcsname \expandafter\lastnamedcs \else \expandafter\page_layouts_place_text_line_unknown \fi#vertical} \permanent\protected\def\doifelselayouttextline#vertical% shown or not {\cdef\currentlayoutelementstate{\namedlayoutelementparameter{#vertical}\c!state}% \ifx\currentlayoutelementstate\v!normal \expandafter\firstoftwoarguments \orelse\ifx\currentlayoutelementstate\v!start \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} \permanent\protected\def\doifelselayoutsomeline#vertical% present or not {\cdef\currentlayoutelementstate{\namedlayoutelementparameter{#vertical}\c!state}% \ifx\currentlayoutelementstate\v!none \expandafter\secondoftwoarguments \orelse\ifx\currentlayoutelementstate\v!high \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} \aliased\let\doiflayouttextlineelse\doifelselayouttextline \aliased\let\doiflayoutsomelineelse\doifelselayoutsomeline \newconditional\resyncaftertextline \defcsname\??layouttextsline\v!normal\endcsname{\page_layouts_place_text_line_indeed} \defcsname\??layouttextsline\empty \endcsname{\page_layouts_place_text_line_indeed} \letcsname\??layouttextsline\v!none\endcsname\gobbletwoarguments \letcsname\??layouttextsline\v!stop\endcsname\gobbletwoarguments \defcsname\??layouttextsline\v!high\endcsname#vertical#height% {\global\resyncaftertextline\conditionaltrue \page_layouts_reset_element_status#vertical} \defcsname\??layouttextsline\v!empty\endcsname#vertical#height% {\page_layouts_reset_element_status#vertical} \defcsname\??layouttextsline\v!start\endcsname#vertical#height% {\page_layouts_reset_element_status#vertical% \page_layouts_place_text_line_indeed#vertical#height} \defcsname\??layouttextsline\v!nomarking\endcsname#vertical#height% {\bgroup \page_layouts_reset_element_status#vertical% \inhibitgetmarking\conditionaltrue \page_layouts_place_text_line_indeed#vertical#height% \egroup} % \setupheadertexts [11] % \definetext [title] [header] [aa] % \setupheadertexts [11] [22] % \definetext [title] [header] [aa] [bb] % \setupheadertexts [text] [11] [22] % \definetext [title] [header] [text] [aa] [bb] % \setupheadertexts [11] [22] [33] [44] % \definetext [title] [header] [aa] [bb] [cc] [dd] % \setupheadertexts [text] [11] [22] [33] [44] % \definetext [title] [header] [text] [aa] [bb] [cc] [dd] \def\page_layouts_place_text_line_unknown#vertical#height% {\global\resyncaftertextline\conditionaltrue \begingroup % new \page_layouts_reset_element_status#vertical% \begincsname\namedlayoutelementhash{#vertical}\textlinestatus\endcsname \begincsname\namedlayoutelementhash{#vertical:\v!text}\textlinestatus\endcsname \begincsname\namedlayoutelementhash{#vertical:\v!margin}\textlinestatus\endcsname \begincsname\namedlayoutelementhash{#vertical:\v!edge}\textlinestatus\endcsname \page_layouts_place_text_line_indeed#vertical#height% \endgroup} \letcsname\??layouttextsline\s!unknown\endcsname\page_layouts_place_text_line_unknown %D The following macro has to be called after a page is flushed. \permanent\protected\def\resetlayouttextlines % public {\begincsname\??layouttextsreset\v!top \endcsname \begincsname\??layouttextsreset\v!header\endcsname \begincsname\??layouttextsreset\v!text \endcsname \begincsname\??layouttextsreset\v!footer\endcsname \begincsname\??layouttextsreset\v!bottom\endcsname \ifconditional\resyncaftertextline \calculateglobalvsizes \page_backgrounds_recalculate \global\resyncaftertextline\conditionalfalse \fi} \permanent\def\getspecificlayouttext#vertical#horizontal#what% {\begincsname\namedlayoutelementhash{#vertical:#horizontal}#what\endcsname} % \settext[header][text][middle][xxx][yyy] \permanent\tolerant\protected\def\settextcontent[#vertical]#spacer[#horizontal]#spacer[#S#one]#spacer[#S#two]#spacer[#S#three]% header text middle text/text {\ifarguments\or\or\or % 3 \defcsname\namedlayoutelementhash{#vertical:#horizontal}\c!middletext\endcsname {\page_layouts_process_element_double{#one}{#one}}% \or % 4 \defcsname\namedlayoutelementhash{#vertical:#horizontal}\begincsname\??layouttextcontent\v!text:#one\endcsname\c!middletext\endcsname {\page_layouts_process_element_double{#two}{#two}}% \or % 5 \defcsname\namedlayoutelementhash{#vertical:#horizontal}\begincsname\??layouttextcontent\v!text:#one\endcsname\c!middletext\endcsname {\page_layouts_process_element_double{#two}{#three}}% \fi} \let\currentlayoutelement\relax %D This will be redefined, so no \type {\frozen} here! \permanent\tolerant\protected\def\resettextcontent[#vertical]#spacer[#horizontal]#spacer[#S#tag]% header text middle {\ifarguments\or\or % 2 \cdef\currentlayoutelement{#vertical:#horizontal}% \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!middletext \resetlayoutelementparameter\c!righttext \or % 3 % \cdef\currentlayoutelement{#vertical:#horizontal}% % \letcsname\layoutelementhash\begincsname\??layouttextcontent\v!text:#tag\endcsname\c!middletext\endcsname\empty \letcsname\namedlayoutelementhash{#vertical:#horizontal}\begincsname\??layouttextcontent\v!text:#tag\endcsname\c!middletext\endcsname\empty \fi} \letcsname\??layouttextcontent\v!text:\c!middle\endcsname\c!middletext \letcsname\??layouttextcontent\v!text:\c!left \endcsname\c!lefttext \letcsname\??layouttextcontent\v!text:\c!right \endcsname\c!righttext %D The placement of a whole line is handled by the next two macros. These are hooked %D into the general purpose token list registers mentioned before. \mutable\let\currentlayouttextline\relax \def\page_layouts_place_text_line_indeed#vertical#height% {\let\currentlayouttextline#vertical% \ifdim#height>\zeropoint\relax % prevents pagenumbers when zero height \page_layouts_place_text_line_left_or_right{#height}% \fi} \def\page_layouts_place_text_line_left_or_right#height% {\goleftonpage \setbox\b_page_layouts_element\vbox to #height {\vsize#height\relax %\hsize\zeropoint % hack so that e.g. after=\hairline gives predictable results \hsize\totaltextwidth \normalbaselines \enforced\let\\\ignoredlinebreak \enforced\let\crlf\ignoredlinebreak \namedlayoutelementparameter\currentlayouttextline\c!before \doifbothsidesoverruled \page_layouts_place_text_line_right \page_layouts_place_text_line_right \page_layouts_place_text_line_left \namedlayoutelementparameter\currentlayouttextline\c!after \vkern\zeropoint}% keep the \dp, beware of \vtops, never change this! \dp\b_page_layouts_element\zeropoint \box\b_page_layouts_element \vkern-#height\relax} \lettonothing\page_layouts_place_extra_text_left % historic \lettonothing\page_layouts_place_extra_text_right % historic \def\page_layouts_place_text_line_right {\hpack {\ifdim\leftedgewidth>\zeropoint \page_layouts_left_edge_element\c!lefttext\c!leftstyle\c!leftcolor\c!leftwidth \fi \ifdim\leftmarginwidth>\zeropoint \page_layouts_left_margin_element\c!lefttext\c!leftstyle\c!leftcolor\c!leftwidth\zerocount \fi \ifdim\makeupwidth>\zeropoint \page_layouts_text_body_element_l_m_r_e \fi \ifdim\rightmarginwidth>\zeropoint \page_layouts_right_margin_element\c!righttext\c!rightstyle\c!rightcolor\c!rightwidth\plusone \fi \ifdim\rightedgewidth>\zeropoint \page_layouts_right_edge_element\c!righttext\c!rightstyle\c!rightcolor\c!rightwidth \fi}} \def\page_layouts_place_text_line_left {\hpack {\ifdim\leftedgewidth>\zeropoint \page_layouts_left_edge_element\c!righttext\c!rightstyle\c!rightcolor\c!rightwidth \fi \ifdim\leftmarginwidth>\zeropoint \page_layouts_left_margin_element\c!righttext\c!rightstyle\c!rightcolor\c!rightwidth\plusone \fi \ifdim\makeupwidth>\zeropoint \page_layouts_text_body_element_e_r_m_l \fi \ifdim\rightmarginwidth>\zeropoint \page_layouts_right_margin_element\c!lefttext\c!leftstyle\c!leftcolor\c!leftwidth\zerocount \fi \ifdim\rightedgewidth>\zeropoint \page_layouts_right_edge_element\c!lefttext\c!leftstyle\c!leftcolor\c!leftwidth \fi}} \def\page_layouts_left_edge_element_indeed#text#style#color#width% {\letfromlayoutelementparameter\p_text#text% \ifempty\p_text \kern\leftedgewidth \else \hbox to \leftedgewidth\bgroup \hss \page_layouts_process_element_indeed#style#color#width% \egroup \fi} \def\page_layouts_left_edge_element#text#style#color#width% {\cdef\currentlayoutelement{\currentlayouttextline:\v!edge}% \page_layouts_place_element_indeed\leftedgewidth {\page_layouts_left_edge_element_indeed#text#style#color#width}% \kern\leftedgedistance} \def\page_layouts_right_edge_element_indeed#text#style#color#width% {\letfromlayoutelementparameter\p_text#text% \ifempty\p_text \kern\rightedgewidth \else \hbox to \rightedgewidth\bgroup \page_layouts_process_element_indeed#style#color#width% \hss \egroup \fi} \def\page_layouts_right_edge_element#text#style#color#width% {\cdef\currentlayoutelement{\currentlayouttextline:\v!edge}% \kern\rightedgedistance \page_layouts_place_element_indeed\rightedgewidth {\page_layouts_right_edge_element_indeed#text#style#color#width}} % margin needs checking! % \hbox to \leftmarginwidth{\hss\layoutelementparameter\c!margintext}% % \hbox to \rightmarginwidth{\layoutelementparameter\c!margintext\hss}% \def\page_layouts_left_margin_element_indeed#text#style#color#width#margintoo% {\letfromlayoutelementparameter\p_text#text% \ifempty\p_text \kern\leftmarginwidth \else \hbox to \leftmarginwidth\bgroup \hss \page_layouts_process_element_indeed#style#color#width% \egroup \fi \ifcase#margintoo\or \letfromlayoutelementparameter\p_text\c!margintext \ifempty\p_text\else \kern-\leftmarginwidth \hbox to \leftmarginwidth\bgroup \hss \p_text % styling ? \egroup \fi \fi} \def\page_layouts_left_margin_element#text#style#color#width#margintoo% {\cdef\currentlayoutelement{\currentlayouttextline:\v!margin}% \page_layouts_place_element_indeed\leftmarginwidth {\page_layouts_left_margin_element_indeed#text#style#color#width#margintoo}% \kern\leftmargindistance} \def\page_layouts_right_margin_element_indeed#text#style#color#width#margintoo% {\letfromlayoutelementparameter\p_text#text% \ifempty\p_text \kern\rightmarginwidth \else \hbox to \rightmarginwidth\bgroup \page_layouts_process_element_indeed#style#color#width% \hss \egroup \fi \ifcase#margintoo\or \letfromlayoutelementparameter\p_text\c!margintext \ifempty\p_text\else \kern-\rightmarginwidth \hbox to \rightmarginwidth\bgroup \p_text % ? styling \hss \egroup \fi \fi} \def\page_layouts_right_margin_element#text#style#color#width#margintoo% {\cdef\currentlayoutelement{\currentlayouttextline:\v!margin}% \kern\rightmargindistance \page_layouts_place_element_indeed\rightmarginwidth {\page_layouts_right_margin_element_indeed#text#style#color#width#margintoo}} \def\page_layouts_text_body_element_indeed_l_m_r_e {\letfromlayoutelementparameter\p_text\c!lefttext \ifempty\p_text \ifempty\page_layouts_place_extra_text_left\else \hbox to \makeupwidth\bgroup \page_layouts_place_extra_text_left \hss \egroup \kern-\makeupwidth \fi \else \hbox to \makeupwidth\bgroup \page_layouts_place_extra_text_left \page_layouts_process_element_indeed\c!leftstyle\c!leftcolor\c!leftwidth \hss \egroup \kern-\makeupwidth \fi \letfromlayoutelementparameter\p_text\c!middletext \ifempty\p_text\else \hbox to \makeupwidth\bgroup \hss \page_layouts_process_element_indeed\c!middlestyle\c!middlecolor\c!middlewidth \hss \egroup \kern-\makeupwidth \fi \letfromlayoutelementparameter\p_text\c!righttext \ifempty\p_text \kern\makeupwidth \else \hbox to \makeupwidth\bgroup \hss \page_layouts_process_element_indeed\c!rightstyle\c!rightcolor\c!rightwidth \egroup \fi} \def\page_layouts_text_body_element_indeed_e_r_m_l {\letfromlayoutelementparameter\p_text\c!righttext \ifempty\p_text\else \hbox to \makeupwidth\bgroup \page_layouts_process_element_indeed\c!rightstyle\c!rightcolor\c!rightwidth \hss \egroup \kern-\makeupwidth \fi \letfromlayoutelementparameter\p_text\c!middletext \ifempty\p_text\else \hbox to \makeupwidth\bgroup \hss \page_layouts_process_element_indeed\c!middlestyle\c!middlecolor\c!middlewidth \hss \egroup \kern-\makeupwidth \fi \letfromlayoutelementparameter\p_text\c!lefttext \ifempty\p_text \ifempty\page_layouts_place_extra_text_right \kern\makeupwidth \else \hbox to \makeupwidth\bgroup \hss \page_layouts_place_extra_text_right \egroup \fi \else \hbox to \makeupwidth\bgroup \hss \page_layouts_process_element_indeed\c!leftstyle\c!leftcolor\c!leftwidth \page_layouts_place_extra_text_right \egroup \fi} \def\page_layouts_text_body_element_l_m_r_e {\cdef\currentlayoutelement{\currentlayouttextline:\v!text}% \page_layouts_place_element_indeed\makeupwidth\page_layouts_text_body_element_indeed_l_m_r_e} \def\page_layouts_text_body_element_e_r_m_l {\cdef\currentlayoutelement{\currentlayouttextline:\v!text}% \page_layouts_place_element_indeed\makeupwidth\page_layouts_text_body_element_indeed_e_r_m_l} \def\page_layouts_place_element_indeed#width#content% {\vbox % to \vsize {\hsize#width\relax \layoutelementparameter\c!before \setlayoutcomponentattribute\currentlayoutelement \hbox \layoutcomponentboxattribute to #width{#content}% \layoutelementparameter\c!after}} %D Although it is far better to use backgrounds for this purpose, one can add a rule %D in the following way. This method makes the rules disappear in case of an empty %D text 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 This code will move to \type {page-flt.tex}. \appendtoks \placerightmarginblock \kern-\rightmarginwidth \to \rightmargintextcontent \appendtoks \placeleftmarginblock \kern-\leftmarginwidth \to \leftmargintextcontent %D \macros %D {definetext} %D %D Some macros ago, we implemented the \type {status} option \type {unknown}. This %D one is used to take care of symbolic texts handlers. %D %D \showsetup{definetext} %D %D The next example demonstrates how we can use this mechanism to provide page %D (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 \permanent\tolerant\protected\def\definetext[#tag]#spacer[#vertical]#spacer[#horizontal]#spacer[#S#a]#spacer[#S#b]#spacer[#S#c]#spacer[#S#d]% {\ifnum\lastarguments<\plusfour \defcsname\namedlayoutelementhash {#vertical}#tag\endcsname{\setuptexts[#vertical][#horizontal]\relax}% 1, 2, 3 \orelse\ifarguments\or\or\or\or \defcsname\namedlayoutelementhash {#vertical}#tag\endcsname{\setuptexts[#vertical][#horizontal][#a]\relax}% 4 \or \defcsname\namedlayoutelementhash{#vertical:#horizontal}#tag\endcsname{\setuptexts[#vertical][#horizontal][#a][#b]\relax}% 5 \or \defcsname\namedlayoutelementhash {#vertical}#tag\endcsname{\setuptexts[#vertical][#horizontal][#a][#b][#c]\relax}% 6 \or \defcsname\namedlayoutelementhash{#vertical:#horizontal}#tag\endcsname{\setuptexts[#vertical][#horizontal][#a][#b][#c][#d]\relax}% 7 \fi} %D A few more page breakers: \installpagebreakmethod \v!empty {\page_otr_flush_all_floats \page_otr_command_next_page \ifcstok{\namedlayoutelementparameter\v!header\c!state}\v!stop\else\setuplayoutelement[\v!header][\c!state=\v!empty]\fi \ifcstok{\namedlayoutelementparameter\v!footer\c!state}\v!stop\else\setuplayoutelement[\v!footer][\c!state=\v!empty]\fi \page_otr_insert_dummy_page} \installpagebreakmethod \v!header {\ifcstok{\namedlayoutelementparameter\v!header\c!state}\v!stop\else\setuplayoutelement[\v!header][\c!state=\v!empty]\fi} \installpagebreakmethod \v!footer {\ifcstok{\namedlayoutelementparameter\v!footer\c!state}\v!stop\else\setuplayoutelement[\v!footer][\c!state=\v!empty]\fi} %D While the header and footer lines are moved away from the main text, the top and %D bottom lines are centered. \setuplayoutelement[\v!top ][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] \setuplayoutelement[\v!header][\c!state=\v!normal,\c!n=0,\c!before=, \c!after=\vss,\c!strut=\v!yes] \setuplayoutelement[\v!text ][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] \setuplayoutelement[\v!footer][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=, \c!strut=\v!yes] \setuplayoutelement[\v!bottom][\c!state=\v!normal,\c!n=0,\c!before=\vss,\c!after=\vss,\c!strut=] %D Moved here from strc-pag: %D %D We reset a previous location but only when it has a pagenumber associated. This %D is a rather messy test but better than the MkII way where we use states and keep %D settings. \let\m_page_layouts_page_number_location \relax \let\m_page_layouts_page_number_location_v\relax \let\m_page_layouts_page_number_location_h\relax \let\m_page_layouts_page_number_location_x\relax \def\page_layouts_place_page_number % also elsewhere .. beware, not \protected else {\strc_pagenumbers_place_location} % test below fails \def\page_layouts_reset_page_number_location {\ifrelax\m_page_layouts_page_number_location_v\else % this can be done better now, no meaning hackery needed \cdef\currentlayoutelement{\m_page_layouts_page_number_location_v:\m_page_layouts_page_number_location_h}% \edef\tempstring{\detokenizedlayoutelementparameter\m_page_layouts_page_number_location_x}% \iftok{\normalmeaningless\tempstring}{\normalmeaningless\page_layouts_place_page_number}% \resetlayoutelementparameter\m_page_layouts_page_number_location_x \fi \fi} \def\page_layouts_set_page_number_location {\cdef\currentlayoutelement{\m_page_layouts_page_number_location_v:\m_page_layouts_page_number_location_h}% \letlayoutelementparameter\m_page_layouts_page_number_location_x\page_layouts_place_page_number \ifx\m_page_layouts_page_number_location_x\c!marginedgetext \let\page_layouts_place_extra_text_left \page_layouts_place_page_number_left \let\page_layouts_place_extra_text_right\page_layouts_place_page_number_right \else \lettonothing\page_layouts_place_extra_text_left \lettonothing\page_layouts_place_extra_text_right \fi} \def\page_layouts_identify_page_number_location {\let\m_page_layouts_page_number_location_v\v!footer \let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!middletext \processallactionsinset[\directpagenumberingparameter\c!location]% [ \v!header=>\let\m_page_layouts_page_number_location_v\v!header,% \v!footer=>\let\m_page_layouts_page_number_location_v\v!footer,% \v!middle=>\let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!middletext,% \v!left=>\let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!lefttext,% \v!right=>\let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!righttext,% \v!inleft=>\let\m_page_layouts_page_number_location_h\v!margin \let\m_page_layouts_page_number_location_x\c!lefttext,% \v!inright=>\let\m_page_layouts_page_number_location_h\v!margin \let\m_page_layouts_page_number_location_x\c!righttext,% \v!inmargin=>\let\m_page_layouts_page_number_location_h\v!margin \def\m_page_layouts_page_number_location_x{\ifdoublesided\c!margintext\else\c!righttext\fi},% \v!margin=>\let\m_page_layouts_page_number_location_h\v!margin \def\m_page_layouts_page_number_location_x{\ifdoublesided\c!margintext\else\c!righttext\fi},% \v!atmargin=>\let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!marginedgetext,% \v!marginedge=>\let\m_page_layouts_page_number_location_h\v!text \let\m_page_layouts_page_number_location_x\c!marginedgetext]} \protected\def\strc_pagenumbers_set_location {\edef\p_strc_pagenumbers_location{\directpagenumberingparameter\c!location}% \ifx\p_strc_pagenumbers_location\m_page_layouts_page_number_location % unchanged \else \let\m_page_layouts_page_number_location\p_strc_pagenumbers_location \page_layouts_reset_page_number_location \ifempty\p_strc_pagenumbers_location % set otherwise \orelse\ifx\p_strc_pagenumbers_location\v!none % set otherwise \else \page_layouts_identify_page_number_location \page_layouts_set_page_number_location \fi \fi} \def\page_layouts_place_page_number_left % historic {\begingroup \setbox\scratchbox\hbox{\ignorespaces\layoutelementparameter\c!marginedgetext\removeunwantedspaces}% \ifzeropt\wd\scratchbox\else \edef\p_strc_pagenumbers_width{\directpagenumberingparameter\c!width}% \ifempty\p_strc_pagenumbers_width \box\scratchbox\tfskip \else \hpack to \p_strc_pagenumbers_width{\box\scratchbox\hss}% \fi \fi \endgroup} \def\page_layouts_place_page_number_right % historic {\begingroup \setbox\scratchbox\hbox{\ignorespaces\layoutelementparameter\c!marginedgetext\removeunwantedspaces}% \ifzeropt\wd\scratchbox\else \edef\p_strc_pagenumbers_width{\directpagenumberingparameter\c!width}% \ifempty\p_strc_pagenumbers_width \tfskip\box\scratchbox \else \hpack to \p_strc_pagenumbers_width{\hss\box\scratchbox}% \fi \fi \endgroup} \strc_pagenumbers_set_location % initializes \newbox\b_page_layouts_element \def\page_layouts_insert_elements {\ifcase\pageornamentstate \page_layouts_place_elements_indeed % we could have a special flag for always ignored \fi} \def\page_layouts_place_elements_indeed {\setbox\b_page_layouts_element\vpack {\dontcomplain \calculatereducedvsizes \page_layouts_swap_margins\v!text \offinterlineskip \vkern\dimexpr-\topheight-\topdistance\relax \the\toptextcontent \vkern\dimexpr\topheight+\topdistance\relax \the\headertextcontent \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax \anch_positions_place_anchors \vkern\dimexpr-\textdistance-\textheight\relax \the\texttextcontent \vkern\textheight \expand\everyendoftextbody \vkern\footerdistance \the\footertextcontent \vkern\dimexpr\footerheight+\bottomdistance\relax \the\bottomtextcontent \vkern\bottomheight \vfilll}% \smashbox\b_page_layouts_element \box\b_page_layouts_element} % only for very special controlled cases or experiments: \newinteger \c_page_scale_lines \newdimension \d_page_box_stretch_delta \newdimension \d_page_box_stretch_criterium \newconditional\c_page_box_check_stretch % The stretch setting can depend on the current lineheight and the % alignment can be set later. So we need to delay. \def\page_box_check_limit_stretch_indeed#1% {\edef\p_limitstretch{\layoutparameter\c!limitstretch}% \ifx\p_limitstretch\v!yes \d_page_box_stretch_criterium\zeropoint \settrue\c_page_box_check_stretch \orelse\ifx\p_limitstretch\v!auto % safeguard for depth without limit set \ifnum\bottomraggednessmode=\plusthree \d_page_box_stretch_criterium2\lineheight \settrue\c_page_box_check_stretch \else \d_page_box_stretch_criterium\maxdimen \setfalse\c_page_box_check_stretch \fi \orelse\ifchkdimension\p_limitstretch\or \d_page_box_stretch_criterium\p_limitstretch\relax \settrue\c_page_box_check_stretch \else \d_page_box_stretch_criterium\maxdimen \setfalse\c_page_box_check_stretch \fi \ifconditional\c_page_box_check_stretch \boxfixstretch\d_page_box_stretch_criterium#1\relax \d_page_box_stretch_delta\boxstretchdelta \fi} \let\page_box_check_limit_stretch\relax % we test for this \appendtoks \edef\p_limitstretch{\layoutparameter\c!limitstretch}% \ifx\p_limitstretch\v!yes \let\page_box_check_limit_stretch\page_box_check_limit_stretch_indeed \orelse\ifx\p_limitstretch\v!auto \let\page_box_check_limit_stretch\page_box_check_limit_stretch_indeed \orelse\ifchkdimension\p_limitstretch\or \let\page_box_check_limit_stretch\page_box_check_limit_stretch_indeed \else \let\page_box_check_limit_stretch\relax % we test for this \fi \to \everysetuplayout \def\page_layouts_check_stretch#1% {\ifcase\bottomraggednessmode \d_page_box_stretch_delta\zeropoint \orelse\ifrelax\page_box_check_limit_stretch \d_page_box_stretch_delta\zeropoint \else \page_box_check_limit_stretch{#1}% \fi} \def\page_insert_body#1#2% {\setbox\b_page_layouts_element\vpack {\offinterlineskip \calculatereducedvsizes \calculatehsizes \page_layouts_swap_margins\v!page \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax \dontleavehmode \hpack to \makeupwidth {\begingroup % \page_layouts_swap_margins\v!page \goleftonpage \ifdim\leftedgewidth>\zeropoint \the\leftedgetextcontent \kern\dimexpr\leftedgewidth+\leftedgedistance\relax \fi \ifdim\leftmarginwidth>\zeropoint \the\leftmargintextcontent \kern\dimexpr\leftmarginwidth+\leftmargindistance\relax \fi \endgroup \page_apply_postprocessors_page{#2}% \settextpagecontent\b_page_layouts_element{#1}{#2}% \page_backgrounds_add_to_text\b_page_layouts_element \page_grids_add_to_box\b_page_layouts_element \box\b_page_layouts_element \begingroup \ifdim\rightmarginwidth>\zeropoint \kern\rightmargindistance \the\rightmargintextcontent \kern\rightmarginwidth \fi \ifdim\rightedgewidth>\zeropoint \kern\rightedgedistance \the\rightedgetextcontent \kern\rightedgewidth \fi \endgroup \hss}}% \smashbox\b_page_layouts_element \box\b_page_layouts_element} %D Long ago (relative to 2023), when Thanh and I were discussing the \PDFTEX\ hz %D features with Hermann Zapf, we side tracked to vertical alignment. Hermann then %D suggested to play with vertical scaling because \quotation {No user will notice %D it}. Some quick experiment at the moment showed that it could work indeed but we %D left it at that (the code stayed around). It is for that reason that this now %D present feature has the key \type {vz}, as variant on \type {hz} (a.k.a.\ %D expansion or fontadjust). \newconditional\c_page_scale_trace_vz \installtextracker {layout.vz} {\c_page_scale_trace_vz\conditionaltrue} {\c_page_scale_trace_vz\conditionalfalse} \installcorenamespace{vzdistance} \def\page_scale_text_box_trace {\writestatus{vz page \the\realpageno}{% %\s!goal=\the\pagegoal, %\s!total=\the\pagetotal, \s!page=\the\pagegoal, \s!text=\the\textheight, \s!height=\the\pagelastheight, \s!depth=\the\pagelastdepth, \s!stretch=\the\pagelaststretch, \s!shrink=\the\pagelastshrink, \s!fill=(\thewithoutunit\pagelastfilstretch,\thewithoutunit\pagelastfillstretch,\thewithoutunit\pagelastfilllstretch)% }} \def\page_scale_text_box_register_box#1% {\scratchheight\boxrepack#1% \scratchdimen\dimexpr\textheight-\scratchheight\relax \global\expandafter\dimensiondef\csname\??vzdistance\the\mofcolumns\endcsname \ifabsdim\scratchdimen>\c_page_scale_lines\lineheight \zeropoint \else \scratchheight \fi \relax \ifconditional\c_page_scale_trace_vz \page_scale_text_box_trace \fi} \def\page_scale_text_box_register_page {\scratchdimen\dimexpr\textheight-\pagelastheight\relax % not \pagegoal as that includes footnotes \global\expandafter\dimensiondef\csname\??vzdistance\the\mofcolumns\endcsname \ifabsdim\scratchdimen>\c_page_scale_lines\lineheight \zeropoint \orelse\ifdim\pagelastshrink>\zeropoint % maybe also stretch \zeropoint \else \pagelastheight \fi \relax \ifconditional\c_page_scale_trace_vz \page_scale_text_box_trace \fi} \def\page_scale_text_box {\scratchdistance\ifcsname\??vzdistance\the\mofcolumns\endcsname\lastnamedcs\else\zeropoint\fi \ifzeropt\scratchdistance \expandafter\gobbleoneargument \else \expandafter\page_scale_text_box_indeed \fi} \def\page_scale_text_box_indeed#1% {\scratchdimen \dimexpr\textheight-\scratchdistance\relax \scratchheight\ht#1% \scratchdepth \dp#1% \scratchwidth \wd#1% \scratchfloat \floatexpr\textheight/\scratchdistance\relax \setbox#1\vpack\bgroup \hpack\bgroup \normalexpanded{\scale %[\c!xscale=\plusthousand,\c!yscale=\scratchcounter] [\c!sx=1,\c!sy=\the\scratchfloat]% {\box#1}}% \egroup \ifconditional\c_page_scale_trace_vz \nointerlineskip \srule \s!height \scratchdimen \s!yoffset 2\scratchdimen \s!xoffset-2\emwidth \s!width 2\emwidth \hpack \s!yoffset \scratchdimen \s!xoffset-2\emwidth \bgroup \edef\tempstring{\semiexpand\formatone{@0.3f}{\the\scratchfloat}}% \writestatus{vz page \the\realpageno}{scaling \tempstring\space applied}% \llap{\infofont\tempstring}% \egroup \fi \egroup \ht#1\scratchheight \dp#1\scratchdepth \wd#1\scratchwidth} \appendtoks \edef\p_lines{\layoutparameter\c!vz}% \ifx\p_lines\v!yes \c_page_scale_lines\plusone \orelse\ifchknumber\p_lines\or \c_page_scale_lines\lastchknumber \else \c_page_scale_lines\zerocount \fi \to \everysetuplayout %D The main text area has to be combined with some additional (tracing) information. %D %D This will be stored as normal and overloaded in page-lyr and later in page-spr we %D overload the the stored version .. eventually i will clear up the experimental %D mess. \ifdefined\page_otr_flush_top_content\else \let\page_otr_flush_top_content\relax \fi \protected\def\settextpagecontent#1#2#3% #2 and #3 will disappear / is overloaded {\setbox#1\hpack to \makeupwidth {\hss % so don't change this \setlayoutcomponentattribute{\v!page:\v!text}% \vpack \layoutcomponentboxattribute to \textheight {\offinterlineskip \freezetextwidth \hsize\textwidth % local variant of \sethsize <<< in columns? \boxmaxdepth\maxdepth \page_otr_flush_top_content \noindent % content can be < \hsize \page_otr_command_package_contents#2#3}% this will vbox \hss}% \dp#1\zeropoint} \protect \endinput