%D \module %D [ file=strc-mar, %D version=2008.10.20, %D title=\CONTEXT\ Structure Macros, %D subtitle=Markings, %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 Structure Macros / Markings} \registerctxluafile{strc-mar}{} \unprotect %D Synchronizing marks is a rather tricky and messy business. When %D setting a mark, a node is added to the list in order for to \TEX\ %D be able to figure out the 3 current marks when a page is made %D (last mark on previous page, first on current page, last on %D current page; in \LUATEX\ we might at one point have the first on %D the next page as well). %D %D Resetting a mark is not easy. An empty one will not erase the last %D one on the previous page for instance. In \LUATEX\ we can clear a %D marks state register with \type {\clearmarks} but since this is an %D immediate operation it might have unwanted side effects when \TEX\ %D has collected several pages of text and finishing off these pages %D uses marks. %D %D In \MKIV\ we provide an alternative model that permits some more %D control over the way marks are used. It is not entirely compatible %D with \MKII\ or previous \MKIV\ implementations but in practice this %D is not a real problem. It's also easier now to extend this mechanism. % if global has side effects we will need to nil it selectively % and optionally enable it in for instance postponed content \definesystemattribute [marks] [global] \installcorenamespace{marking} \installcommandhandler \??marking {marking} \??marking \newconditional\inhibitgetmarking % will become private \newconditional\inhibitsetmarking % will become private \newtoks \everymarking \unexpanded\def\relatemarking {\dodoubleempty \strc_markings_relate } \unexpanded\def\setmarking {\dosingleargument\strc_markings_set } \let\marking\setmarking \unexpanded\def\resetmarking {\dosingleargument\strc_markings_reset } \unexpanded\def\synchronizemarking{\dotripleargument\strc_markings_synchronize} \appendtoks \clf_definemarking{\currentmarking}{\currentmarkingparent}% \to \everydefinemarking \def\strc_markings_relate[#1][#2]% {\clf_relatemarking{#1}{#2}} \def\strc_markings_set[#1]#2% {\ifconditional\inhibitsetmarking % nothing \else \doifelse{\namedmarkingparameter{#1}\c!expansion}\v!yes {\clf_setmarking{#1}{#2}} {\clf_setmarking{#1}{\detokenize{#2}}}% \fi} \def\strc_markings_reset[#1]% {\clf_resetmarking{#1}} \def\strc_markings_synchronize[#1][#2][#3]% #1=class #2=boxnumber (some day also name) #3=options, maybe second argument table {\ifvoid#2\else\clf_synchronizemarking{#1}#2{#3}\fi} \def\doifelsemarking#1% no \noexpanded {\clf_doifelsemarking{#1}} \let\doifmarkingelse \doifelsemarking % \appendtoks % \strc_markings_synchronize[\v!page][\normalpagebox][\v!keep]% keep if no marks % \to \everybeforepagebody % defaults \setupmarking [\c!expansion=\v!no, \c!separator=\space\emdash\space, \c!filtercommand=\firstofoneargument, \c!state=\v!start] % fetching, regular interface \unexpanded\def\getmarking {\ifconditional\inhibitgetmarking \expandafter\dotripleargument\expandafter\strc_markings_get_nop \else \expandafter\dotripleargument\expandafter\strc_markings_get_yes \fi} \def\strc_markings_get_nop[#1][#2][#3]% {} \def\strc_markings_get_yes[#1][#2][#3]% {\doif{\namedmarkingparameter{#1}\c!state}\v!start {\begingroup \setsystemmode\v!marking \the\everymarking \ifthirdargument \clf_getmarking{#1}{#2}{#3}% \else \clf_getmarking{#1}{\v!page}{#2}% \fi \endgroup}} % the fetchers are fully expandable: [name][method] \def\fetchonemark[#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchonemark {#1}{\v!page}{#3}\fi} \def\fetchtwomarks [#1]{\ifconditional\inhibitgetmarking\else\clf_fetchtwomarks{#1}{\v!page}\fi} \def\fetchallmarks [#1]{\ifconditional\inhibitgetmarking\else\clf_fetchallmarks{#1}{\v!page}\fi} \let\fetchmark\fetchonemark % also fully expandable but here we have: [name][range][method] \def\fetchonemarking[#1]#2[#3]#4[#5]{\ifconditional\inhibitgetmarking\else\clf_fetchonemark {#1}{#3}{#5}\fi} \def\fetchtwomarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchtwomarks{#1}{#3}\fi} \def\fetchallmarkings [#1]#2[#3]{\ifconditional\inhibitgetmarking\else\clf_fetchallmarks{#1}{#3}\fi} \let\fetchmarking\fetchonemarking \def\markingseparator#1{\namedmarkingparameter{#1}\c!separator} \def\markingcommand #1{\namedmarkingparameter{#1}\c!filtercommand} %D Experimental: %D %D \starttyping %D \definemarking[boxmark] %D %D \setbox0\ruledvbox{ %D \marking[boxmark]{tufte} \input tufte \par %D \marking[boxmark]{ward} \input ward \par %D } %D %D \synchronizemarking[zerobox][0] \box0 %D %D marks: (\getmarking[boxmark][zerobox][first],\getmarking[boxmark][zerobox][last]) %D \stoptyping \protect \endinput