summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/strc-mar.mkiv
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2009-08-23 11:11:32 +0000
committerTaco Hoekwater <taco@elvenkind.com>2009-08-23 11:11:32 +0000
commit8fc3039c82d48605b5ca8b2eda3f4fdd755681e1 (patch)
tree3cd9bbdd599bc4d1ac0409e167fee2136e4c0ec9 /Master/texmf-dist/tex/context/base/strc-mar.mkiv
parent850fc99b7cd3ae7a20065531fe866ff7bae642ec (diff)
this is context 2009.08.19 17:10
git-svn-id: svn://tug.org/texlive/trunk@14827 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/strc-mar.mkiv')
-rw-r--r--Master/texmf-dist/tex/context/base/strc-mar.mkiv493
1 files changed, 493 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/strc-mar.mkiv b/Master/texmf-dist/tex/context/base/strc-mar.mkiv
new file mode 100644
index 00000000000..8dbbb232caf
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/strc-mar.mkiv
@@ -0,0 +1,493 @@
+%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 / Hans Hagen]
+%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}{1.001}
+
+\unprotect
+
+%D Old stuff.
+
+\newtoks \listofmarks
+
+\let \getmarks \gobbleoneargument
+\let \getallmarks \relax
+\let \getsplitmarks \gobbleoneargument
+\let \getallsplitmarks \relax
+
+%D \macros
+%D {expandmarks}
+%D
+%D We can force expansion of marks with the following switch.
+
+% Synchronizing marks is a rather tricky and messy business. When
+% setting a mark, a node is added to the list in order for to \TEX\
+% be able to figure out the 3 current marks when a page is made
+% (last mark on previous page, first on current page, last on
+% current page; in \LUATEX\ we might at one point have the first on
+% the next page as well).
+
+% Resetting a mark is not easy. An empty one will not erase the last
+% one on the previous page for instance. In \LUATEX\ we can clear a
+% marks state register with \type {\clearmarks} but since this is an
+% immediate operation it might have unwanted side effects when \TEX\
+% has collected several pages of text and finishing off these pages
+% uses marks.
+
+% In \MKIV\ we provide a model that permits some control over the
+% way marks are used. It is not entirely compatible with \MKII\ but
+% in practice this is not a real problem. Quality has a price.
+
+% In fact we define multiple marks per visible mark and define
+% additional ones on the fly. This has some price in terms of used
+% mark registers but given the way that we fill marks in \MKIV\
+% their accumulated content is not really the issue. Also,
+% periodically we cleanup any leftovers.
+
+\newif\ifexpandmarks \expandmarkstrue
+
+\def\marksomecs #1#2{\csname\string#1:m:\number#2\endcsname}
+\def\markautocs #1{\csname\string#1:m:\number\csname\string#1:s\endcsname\endcsname}
+\def\markmaincs #1{\csname\string#1:m\endcsname}
+\def\markresetcs #1{\csname\string#1:r\endcsname}
+\def\markstatecs #1{\csname\string#1:s\endcsname}
+\def\markcurrentcs#1{\csname\string#1:c\endcsname}
+\def\marktokscs #1{\csname\string#1:t\endcsname}
+
+\def\renewmarks#1%
+ {\ifx#1\relax
+ % \writestatus\m!systems{defining low level mark: \string#1}%
+ \newmarks#1%
+ \else
+ \clearmarks#1%
+ \fi}
+
+\def\definenewmark#1%
+ {\ifcsname\string#1:m\endcsname\else
+ \@EA\@EA\@EA\newcount \markstatecs #1\global\markstatecs#1\plusone
+ \@EA\@EA\@EA\renewmarks\markautocs #1%
+ \@EA\@EA\@EA\renewmarks\markmaincs #1%
+ \@EA\@EA\@EA\renewmarks\markresetcs #1%
+ \@EA\@EA\@EA\newtoks \marktokscs #1%
+ \@EA\@EA\@EA\let \markcurrentcs#1\empty
+ \listofmarks\expandafter{\the\listofmarks\checkmark#1}%
+ \fi}
+
+\long\def\setmark#1#2% marks expand
+ {\@EA\@EA\@EA\xdef \markcurrentcs#1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}%
+ \marks\markautocs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level
+ \marks\markmaincs #1{\ifexpandmarks#2\else\normalunexpanded{#2}\fi}% we could expand current one level
+ \marks\markresetcs #1{\number\markstatecs#1}}
+
+\def\resetmark#1%
+ {\global\advance\markstatecs#1\plusone
+ \@EA\@EA\@EA\glet\markcurrentcs#1\empty
+ \@EA\@EA\@EA\renewmarks\markautocs#1%
+ \the\marktokscs#1\relax}
+
+\def\addmarkreset#1#2%
+ {\global\marktokscs#2\@EA{\the\marktokscs#2\resetmark#1}}
+
+% already there: \prependtoks \getallmarks \to \everybeforepagebody
+%
+% \def\getallmarks{\the\listofmarks}
+
+\let\checkmark\gobbleoneargument
+
+\prependtoks \clearmarkswhenemptypage \to \everybeforepagebody
+
+\def\clearmarkswhenemptypage
+ {\iffalse % check if page is empty
+ \clearallmarks
+ \fi}
+
+\def\clearallmarks
+ {\let\checkmark\clearmarkchain
+ \the\listofmarks
+ \let\checkmark\gobbleoneargument}
+
+\def\clearmarkchain#1%
+ {\@EA\@EA\@EA\clearmarks\markmaincs#1%
+ \@EA\@EA\@EA\clearmarks\markresetcs#1%
+ \@EA\doclearmarkchain\@EA{\number\csname\string#1:s\endcsname}#1%
+ \@EA\@EA\@EA\glet\markcurrentcs#1\empty
+ \global\markstatecs#1\plusone}
+
+\def\doclearmarkchain#1#2%
+ {\@EA\@EA\@EA\clearmarks\marksomecs#1{#2}%
+ \@EA\doclearmarkchain\@EA#1\@EA{\number\numexpr#2+\minusone}}
+
+% Fetching (expandable versions, so no intermediate counter):
+
+\def\currenttopmarknumber #1{\number0\topmarks \markresetcs#1}
+\def\currentfirstmarknumber#1{\number0\firstmarks\markresetcs#1}
+\def\currentbotmarknumber #1{\number0\botmarks \markresetcs#1}
+
+\def\checkedcurrentmarkrange#1{[\currenttopmarknumber#1,\currentfirstmarknumber#1,\currentbotmarknumber#1]}
+
+\def\checkedcurrentmarks{\markcurrentcs} % #1 shared current mark
+
+\let\currentsplittopmarknumber\currenttopmarknumber
+\let\normalsplittopmarks \normaltopmarks
+
+\def\uncheckedautotopmark {\normaltopmarks \markautocs} % #1
+\def\uncheckedautofirstmark {\normalfirstmarks \markautocs} % #1
+\def\uncheckedautobotmark {\normalbotmarks \markautocs} % #1
+\def\uncheckedautosplittopmark {\normalsplittopmarks \markautocs} % #1
+\def\uncheckedautosplitfirstmark {\normalsplitfirstmarks\markautocs} % #1
+\def\uncheckedautosplitbotmark {\normalsplitbotmarks \markautocs} % #1
+
+\def\uncheckedmaintopmark {\normaltopmarks \markmaincs} % #1
+\def\uncheckedmainfirstmark {\normalfirstmarks \markmaincs} % #1
+\def\uncheckedmainbotmark {\normalbotmarks \markmaincs} % #1
+\def\uncheckedmainsplittopmark {\normalsplittopmarks \markmaincs} % #1
+\def\uncheckedmainsplitfirstmark {\normalsplitfirstmarks\markmaincs} % #1
+\def\uncheckedmainsplitbotmark {\normalsplitbotmarks \markmaincs} % #1
+
+\def\checkedpagetopmarks #1{\ifcase\currentbotmarknumber #1\else\normaltopmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagefirstmarks #1{\ifcase\currentbotmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagebotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedpagesplittopmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+\def\checkedpagesplitfirstmarks#1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+\def\checkedpagesplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+
+\def\checkedfulltopmarks #1{\ifcase\currenttopmarknumber #1\else\normaltopmarks \marksomecs#1{\currenttopmarknumber #1}\fi}
+\def\checkedfullfirstmarks #1{\ifcase\currentfirstmarknumber #1\else\normalfirstmarks \marksomecs#1{\currentfirstmarknumber #1}\fi}
+\def\checkedfullbotmarks #1{\ifcase\currentbotmarknumber #1\else\normalbotmarks \marksomecs#1{\currentbotmarknumber #1}\fi}
+\def\checkedfullsplittopmarks #1{\ifcase\currentsplittopmarknumber #1\else\normalsplittopmarks \marksomecs#1{\currentsplittopmarknumber #1}\fi}
+\def\checkedfullsplitfirstmarks#1{\ifcase\currentsplitfirstmarknumber#1\else\normalsplitfirstmarks\marksomecs#1{\currentsplitfirstmarknumber#1}\fi}
+\def\checkedfullsplitbotmarks #1{\ifcase\currentsplitbotmarknumber #1\else\normalsplitbotmarks \marksomecs#1{\currentsplitbotmarknumber #1}\fi}
+
+% Interface macros:
+
+\def\getcurrentmark {\checkedcurrentmarks }
+\def\gettopmark {\checkedfulltopmarks }
+\def\getfirstmark {\checkedfullfirstmarks }
+\def\getbotmark {\checkedfullbotmarks }
+\def\getsplittopmark {\checkedfullsplittopmarks }
+\def\getsplitfirstmark {\checkedfullsplitfirstmarks}
+\def\getsplitbotmark {\checkedfullsplitbotmarks }
+
+\def\getbottommark {\getbotmark}
+\def\getsplitbottommark{\getsplitbotmark}
+
+%D Some of these will go away (in the process of rewriting).
+
+\let \newmark \definenewmark
+\let \newpersistentmark \newmarks
+\let \normalsetmark \setmark
+\let \rawnewmark \newmarks
+\let \rawdefinemark \newmarks
+\let \rawsetmark \normalmarks
+\let \rawgettopmark \normaltopmarks
+\let \rawgetfirstmark \normalfirstmarks
+\let \rawgetbotmark \normalbotmarks
+\let \rawgetsplitbotmark \normalsplitbotmarks
+\let \rawgetsplitfirstmark \normalsplitfirstmarks
+\let \rawgetsplittopmark \normalsplitfirstmarks
+
+\let \noninterferingmarks \relax % old color interference related hack
+
+%D Next comes the layer around the previous mechanism.
+%D
+%D Parameters
+
+\def\markingparameter #1#2{\csname\domarkingparameter{\??mk#1}#2\endcsname}
+\def\domarkingparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\@EA\domarkingparentparameter\csname#1\s!parent\endcsname#2\fi}
+\def\domarkingparentparameter#1#2{\ifx#1\relax\s!empty\else\domarkingparameter#1#2\fi}
+\def\markingcoupling #1{\ifcsname\??mk#1\c!coupling\endcsname\@EA\markingcoupling\csname\??mk#1\c!coupling\endcsname\else#1\fi}
+
+\let\mainmarking\markingcoupling % compatibility
+
+\def\doifelsemarking#1%
+ {\ifcsname\??mk#1\c!coupling\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\def\dowithmarkcommandone#1#2% \command {mark}
+ {\expandafter#1\csname\??mk:\markingcoupling{#2}\endcsname}
+
+\def\dowithmarkcommandtwo#1#2#3% \command {mark} {mark}
+ {\expandafter#1\csname\??mk:\markingcoupling{#2}\expandafter\endcsname\csname\??mk:\markingcoupling{#3}\endcsname}
+
+\def\setupmarking
+ {\dodoubleargument\dosetupmarking}
+
+\def\dosetupmarking[#1][#2]%
+ {\def\docommand##1{\getparameters[\??mk##1][#2]}%
+ \processcommalist[#1]\docommand}
+
+%D The filtercommand key is used to hook in a filtering command. Users are
+%D adviced not to misuse this key.
+
+\getparameters
+ [\??mk]
+ [\c!expansion=\v!no, % saves a macro
+ \c!separator={\space\emdash\space},
+ \c!limittext=\@@kolimittext,
+ \c!filtercommand=\firstofoneargument,
+ \c!state=\v!start]
+
+\let\alldefinedmarks\empty
+
+\def\definemarking
+ {\dodoubleempty\dodefinemarking}
+
+\def\dodefinemarking[#1][#2]%
+ {\doifelsenothing{#2}\donormaldefinemarking\docloneddefinemarking[#1][#2]}
+
+\def\donormaldefinemarking[#1][#2]% #2 empty
+ {\ifcsname\??mk#1\s!parent\endcsname
+ % already defined
+ \else
+ \letgvalue{\??mk#1\s!parent}\??mk
+ \dowithmarkcommandone\newmark{#1}%
+ \doglobal\addtocommalist{#2}\alldefinedmarks
+ \ifproductionrun\showmessage\m!systems{13}{#1,[#1]}\fi
+ \fi}
+
+\def\docloneddefinemarking[#1][#2]%
+ {\ifcsname\??mk#1\s!parent\endcsname \else \ifcsname\??mk#2\s!parent\endcsname
+ \doifnot{#1}{#2}%
+ {\setxvalue{\??mk#1\s!parent}{\??mk#2}%
+ \setxvalue{\??mk#1\c!coupling}{#2}%
+ \ifproductionrun\showmessage\m!systems{13}{#1,[#2]}\fi}%
+ \fi \fi}
+
+\def\decouplemarking[#1]%
+ {\letbeundefined{\??mk#1\c!coupling}}
+
+\def\couplemarking[#1]#2[#3]% couple 1 to 2 (this macro is not really needed)
+ {\setvalue{\??mk#1\c!coupling}{#3}}
+
+\def\relatemarking[#1]#2[#3]% define 1 as child of 2
+ {\dowithmarkcommandtwo\addmarkreset{#1}{#3}}
+
+\def\definerawmarking[#1]%
+ {\dododefinemarking[#1][#1]%
+ \getgparameters[\??mk#1][\c!limittext=]} % global !
+
+% \decouplemarking[#1]% % no coupling with sections
+
+\def\fastresetmarker#1%
+ {\ifcsname\??mk#1\s!parent\endcsname
+ \dowithmarkcommandone\resetmark{#1}%
+ \fi}
+
+\def\fastresetmarkerlist[#1]%
+ {\normalexpanded{\noexpand\rawprocesscommalist[#1]}\fastresetmarker}
+
+\def\resetmarking
+ {\dosingleargument\doresetmarking}
+
+\def\doresetmarking[#1]%
+ {\processcommalist[#1]\fastresetmarker}
+
+%D Used elsewhere:
+
+\let\nomarking\empty
+
+%D Basic fetching:
+
+\letvalue{\??mk::\??mk::\v!previous}\firstoffourarguments
+\letvalue{\??mk::\??mk::\v!first }\secondoffourarguments
+\letvalue{\??mk::\??mk::\v!last }\thirdoffourarguments
+\letvalue{\??mk::\??mk::\v!current }\fourthoffourarguments
+
+\letvalue{\??mk\??mk\v!previous}\gettopmark
+\letvalue{\??mk\??mk\v!first }\getfirstmark
+\letvalue{\??mk\??mk\v!last }\getbotmark
+\letvalue{\??mk\??mk\v!current }\getcurrentmark
+
+\letvalue{\??mk\??mk\v!column:\v!first}\getsplitfirstmark
+\letvalue{\??mk\??mk\v!column:\v!last }\getsplitbottommark
+
+\def\fetchmark[#1]#2[#3]% % expandable / never use \unexpanded
+ {\ifcsname\??mk::#1\endcsname % saved mark
+ \markingparameter{#1}\c!filtercommand{\csname\??mk::\??mk::#3\@EA\@EA\@EA\endcsname\csname\??mk::#1\endcsname}%
+ \else\ifcsname\??mk#1\s!parent\endcsname % real mark
+ \markingparameter{#1}\c!filtercommand{\expandafter\dowithmarkcommandone\csname\??mk\??mk#3\endcsname{#1}}%
+ \fi\fi}
+
+\def\fetchtwomarks[#1]%
+ {\dofetchtwomarks[#1][#1]}
+
+\def\fetchallmarks[#1]%
+ {\dofetchallmarks[#1][#1]}
+
+\def\dofetchtwomarks[#1][#2]% class class:tag
+ {\doifsomething{\fetchmark[#2][\v!first]}
+ {\fetchmark[#2][\v!first]%
+ \doifsomething{\fetchmark[#2][\v!last]}
+ {\doifnot{\fetchmark[#2][\v!first]}{\fetchmark[#2][\v!last]}
+ {\markingparameter{#1}\c!separator\fetchmark[#2][\v!last]}}}}
+
+\def\dofetchallmarks[#1][#2]%
+ {\doifsomething{\fetchmark[#2][\v!first]}
+ {\doifsomething{\fetchmark[#2][\v!previous]}
+ {\doifnot{\fetchmark[#2][\v!previous]}{\fetchmark[#2][\v!first]}
+ {\fetchmark[#2][\v!previous]\markingparameter{#1}\c!separator}}}%
+ \fetchtwomarks[#1][#2]}
+
+% \newtoks \everymarking
+
+% \def\Interesting{\doifmodeelse{*\v!marking}{Interesting}{Boring}}
+% \setupheadertexts[chapter]
+% \starttext
+% \chapter{This Is \Interesting}
+% \stoptext
+
+\def\markingnomarking#1{\splitsequence{\markingparameter{#1}\c!limittext}} % #2
+
+\def\dogetmarking[#1][#2][#3]%
+ {\doif{\markingparameter{#1}\c!state}\v!start
+ {\bgroup
+ \setsystemmode\v!marking
+ \the\everymarking
+ \def\nomarking{\markingnomarking{#1}}% just for good old times, might disappear
+ \ifthirdargument
+ \dodogetmarking{#3}{#1}{#1:#2}{#3}%
+ \else
+ \dodogetmarking{#2}{#1}{#1}{#2}%
+ \fi
+ \egroup}}
+
+\def\dodogetmarking#1#2#3#4% to be made faster
+ {\processaction % slow
+ [#1]
+ [ \v!both=>{\dofetchtwomarks[#2][#3]},
+ \v!all=>{\dofetchallmarks[#2][#3]},
+ \s!default=>{\fetchmark[#3][\v!first]},
+ \s!unknown=>{\fetchmark[#3][#4]}]}
+
+\def\nogetmarking[#1][#2][#3]%
+ {}
+
+\unexpanded\def\getmarking
+ {\dotripleargument\dogetmarking}
+
+\let\setsomemark\setmark
+
+\def\setmarking
+ {\dosingleargument\dosetmarking}
+
+\def\dosetmarking[#1]#2%
+ {\ifcsname\??mk#1\s!parent\endcsname
+ \begingroup
+ \doifelse{\markingparameter{#1}\c!expansion}\v!yes\expandmarkstrue\expandmarksfalse
+ \dowithmarkcommandone\setsomemark{#1}{#2}%
+ \endgroup
+ \fi}
+
+\let\marking\setmarking
+
+% to be adapted for mkiv:
+%
+% this version can be used when a page is built up in steps without
+% feedback of the otr'd list to the mvl (i.e.\ a page made of pages,
+% as in column sets where content is buffered)
+
+% reset at begin
+% preset before page
+% bubble in column
+% refresh at end
+
+% marks is a kind of toks, so maybe we need a low level \the\marks
+%
+% use \normalunexpanded here
+
+\def\refreshsavedmark[#1][#2]% mark tag (packing saves many hash entries)
+ {\setxvalue{\??mk::#1:#2}%
+ {{\@EA\ifx\csname\??mk::#1:pp\endcsname\relax
+ % empty
+ \else
+ \csname\??mk::#1:pp\endcsname
+ \fi}%
+ {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax
+ \fetchmark[#1][\v!first]%
+ \else
+ \csname\??mk::#1:ff\endcsname
+ \fi}%
+ {\fetchmark[#1][\v!last]}%
+ {\fetchmark[#1][\v!current]}}%
+ \setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!first]}%
+ \letgvalue{\??mk::#1:ff}\relax
+ }
+
+\def\bubblesavedmark[#1][#2]% no packing (not now, maybe make a six-pack later)
+ {\@EA\ifx\csname\??mk::#1:ff\endcsname\relax
+ \setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}%
+ \fi}
+
+\def\resetsavedmark[#1][#2]% mark tag
+ {\doifelsenothing{\fetchmark[#1][\v!previous]}
+ {\letgvalue{\??mk::#1:pp}\relax}
+ {\setxvalue{\??mk::#1:pp}{\fetchmark[#1][\v!previous]}}%
+ \doifelsenothing{\fetchmark[#1][\v!first]}
+ {\letgvalue{\??mk::#1:ff}\relax}
+ {\setxvalue{\??mk::#1:ff}{\fetchmark[#1][\v!first]}}%
+ \letgvalue{\??mk::#1:#2}\emptysavedmark}
+
+\def\presetsavedmark[#1][#2]% mark tag
+ {\letgvalue{\??mk::#1:#2}\emptysavedmark}
+
+\def\emptysavedmark{{}{}{}{}}
+
+% new (can be used in column sets)
+%
+% \getsavedmarking[M][previous]
+% \getsavedmarking[M][first]
+% \getsavedmarking[M][last]
+
+\def\getsavedmarking
+ {\dodoubleargument\dogetsavedmarking}
+
+\def\dogetsavedmarking[#1][#2]%
+ {\doifelse{#2}\v!previous
+ {\getmarking[#1][1][\v!previous]}
+ {\doifelse{#2}\v!first
+ {\getmarking[#1][1][\v!first]}
+ {\getmarking[#1][\v!last]}}}
+
+%D And then \unknown\ we had a chaptertitle packaged in a
+%D makeup environment. And we don't want to loose marks there!
+
+\newbox\collectedmarks
+
+\def\flushmarks % use with care to avoid empty pages
+ {\ifvoid\collectedmarks\else\unhbox\collectedmarks\fi}
+
+\def\postponemarks
+ {\let\setsomemark\postponemark}
+
+\def\postponemark#1#2%
+ {\global\setbox\collectedmarks\hbox{\unhbox\collectedmarks\setmark{#1}{#2}}}
+
+\protect \endinput
+
+% todo: make it work in balancing
+%
+% \definemarking[vers][]
+% \setupheadertexts
+% [\doiftext{\getmarking[vers][first]}
+% {\doiftextelse{\getmarking[vers][column:last]}
+% {\getmarking[vers][first] -- \getmarking[vers][column:last]}
+% {\getmarking[vers][first]}}]
+% \starttext
+% \startcolumns[n=2,balance=no]
+% \dorecurse{10}{\normalexpanded{\noexpand\marking[vers]{\recurselevel}} \recurselevel:\dorecurse{4}{\input ward } \endgraf}
+% \stopcolumns
+% \stoptext