strc-mar.mkxl /size: 9 Kb    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=strc-mar,
3%D        version=2008.10.20,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Markings,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Structure Macros / Markings}
15
16\registerctxluafile{strc-mar}{autosuffix}
17
18\unprotect
19
20%D Synchronizing marks is a rather tricky and messy business. When setting a mark, a
21%D node is added to the list in order for to \TEX\ be able to figure out the 3
22%D current marks when a page is made (last mark on previous page, first on current
23%D page, last on current page; in \LUATEX\ we might at one point have the first on
24%D the next page as well).
25%D
26%D Resetting a mark is not easy. An empty one will not erase the last one on the
27%D previous page for instance. In \LUATEX\ we can clear a marks state register with
28%D \type {\clearmarks} but since this is an immediate operation it might have
29%D unwanted side effects when \TEX\ has collected several pages of text and
30%D finishing off these pages uses marks.
31%D
32%D In \MKIV\ we provide an alternative model that permits some more control over the
33%D way marks are used. It is not entirely compatible with \MKII\ or previous \MKIV\
34%D implementations but in practice this is not a real problem. It's also easier now
35%D to extend this mechanism.
36
37%D In \LUAMETATEX\ we have extended the marks mechanism with a few handy options.
38%D First of all we have automigration built in for inserts and marks (so we no
39%D longer need to do that in \LUA) and marks can be properly flushed.
40
41% \ifdefined\automigrationmode \automigrationmode0 \fi
42% \starttext
43% \dorecurse{10}{
44%     \dontleavehmode\setbox0\hbox{SAMPLE #1}\box0
45%     \marks\foomark{sample #1}%
46%     \samplefile{tufte}\par
47% }%
48% \stoptext
49
50% current
51
52% column:n | n | column | etc ... now only column:n
53
54% default page all keep
55
56%definesystemattribute [marks] [global]
57
58\installcorenamespace{marking}
59\installcorenamespace{markingclass}
60\installcorenamespace{markingsyncs}
61\installcorenamespace{markingfilter}
62
63\installcommandhandler \??marking {marking} \??marking
64
65\newconditional\inhibitgetmarking % will become private
66\newconditional\inhibitsetmarking % will become private
67
68\newtoks       \everymarking
69
70% \clf_definemarking{\currentmarking}{\currentmarkingparent}%
71
72\appendtoks
73    \ifcsname\??markingclass\currentmarking\endcsname\else
74        \ifempty\currentmarkingparent
75            \expandafter\newmarks\csname\??markingclass\currentmarking\endcsname
76            \expandafter\newtoks \csname\??markingsyncs\currentmarking\endcsname
77        \else
78            \expandafter\letcsname\??markingclass\currentmarking\expandafter\endcsname\csname\??markingclass\currentmarkingparent\endcsname
79            \expandafter\letcsname\??markingsyncs\currentmarking\expandafter\endcsname\csname\??markingsyncs\currentmarkingparent\endcsname
80        \fi
81    \fi
82\to \everydefinemarking
83
84\permanent\protected\tolerant\def\relatemarking[#1]#*[#2]%
85  {\ifarguments\or\else
86     \xtoksapp\csname\??markingsyncs#2\endcsname{%
87       \flushmarks\csname\??markingclass#1\endcsname
88       \noexpand\the\begincsname\??markingsyncs#1\endcsname
89     }%
90   \fi}
91
92\permanent\protected\tolerant\def\clearmarking[#1]%
93  {\ifarguments\else
94     \begingroup
95     \clearmarks\csname\??markingclass#1\endcsname
96     \enforced\let\flushmarks\clearmarks
97     \the\csname\??markingsyncs#1\endcsname
98     \endgroup
99   \fi}
100
101\permanent\protected\tolerant\def\resetmarking[#1]%
102  {\ifarguments\else
103     % probably best: \dontleavehmode
104     \the\csname\??markingsyncs#1\endcsname
105   \fi}
106
107\permanent\protected\tolerant\def\resetsynchronizemarking[#1]%
108  {\clf_resetsynchronizemarking{#1}}
109
110\tolerant\def\synchronizemarking[#1]#*[#2]#*[#3]% #3: options
111  {\clf_synchronizemarking{#1}\plusone\numexpr#2\relax}
112
113\def\strc_markings_synchronize#1#2#3% category n box
114  {\ifvoid#3\orelse\ifcstok{#1}\v!page\else
115     \clf_synchronizemarking{#1}\numexpr#2\relax\numexpr#3\relax
116   \fi}
117
118\permanent\def\doifelsemarking#1%
119  {\ifcondition\ifcommandhandler\??marking{#1}%
120     \expandafter\firstoftwoarguments
121   \else
122     \expandafter\secondoftwoarguments
123   \fi}
124
125\permanent\protected\tolerant\def\setmarking[#1]#:#2%
126  {\ifarguments\orelse\ifconditional\inhibitsetmarking\else
127     % so no: \dontleavehmode
128     \the\csname\??markingsyncs#1\endcsname
129     \ifcstok{\namedmarkingparameter{#1}\c!expansion}\v!yes
130       \normalexpanded{%
131          \ifvmode\expandafter\flushatnextpar\else\expandafter\firstofoneargument\fi
132            {\marks\csname\??markingclass#1\endcsname{#2}}%
133       }%
134     \else
135       \ifvmode\expandafter\flushatnextpar\else\expandafter\firstofoneargument\fi
136          {\marks\csname\??markingclass#1\endcsname{#2}}%
137     \fi
138   \fi}
139
140\aliased\let\marking        \setmarking
141\aliased\let\doifmarkingelse\doifelsemarking
142
143% defaults
144
145\setupmarking
146  [\c!expansion=\v!no,
147   \c!separator=\space\emdash\space,
148   \c!filtercommand=\firstofoneargument,
149   \c!state=\v!start]
150
151% fetching, regular interface
152
153\permanent\protected\def\getmarking
154  {\ifconditional\inhibitgetmarking
155     \expandafter\strc_markings_get_nop
156   \else
157     \expandafter\strc_markings_get_yes
158   \fi}
159
160\tolerant\def\strc_markings_get_nop[#-]#*[#-]#*[#-]%
161  {}
162
163\tolerant\def\strc_markings_get_yes[#1]#*[#2]#*[#3]%
164  {\ifarguments\orelse\ifcstok{\namedmarkingparameter{#1}\c!state}\v!start
165     \begingroup
166     \setsystemmode\v!marking
167     \expand\everymarking
168     \ifparameter#3\or
169       \ifcstok{#2}\v!page
170         \markingcommand{#1}{\csname\??markingfilter#3\endcsname{#1}}%
171       \else
172         \markingcommand{#1}{\clf_getsynchronizemarking\begincsname\??markingclass#1\endcsname{#2}{#3}}%
173       \fi
174     \orelse\ifparameter#2\or
175       \markingcommand{#1}{\csname\??markingfilter#2\endcsname{#1}}%
176     \else
177       \markingcommand{#1}{\csname\??markingfilter\v!default\endcsname{#1}}%
178     \fi
179     \endgroup
180  \fi}
181
182% previous      : last before sync        next   : first after sync
183% top           : first in sync           bottom : last in sync
184% first|default : first not top in sync   last   : last not bottom in sync
185
186% current
187
188\defcsname\??markingfilter\v!previous\endcsname#1{\topmarks    \csname\??markingclass#1\endcsname}
189\defcsname\??markingfilter\v!next    \endcsname#1{\botmarks    \csname\??markingclass#1\endcsname}
190
191%defcsname\??markingfilter\v!top     \endcsname#1{\topmarks    \csname\??markingclass#1\endcsname}
192\defcsname\??markingfilter\v!top     \endcsname#1{\firstmarks  \csname\??markingclass#1\endcsname}
193\defcsname\??markingfilter\v!bottom  \endcsname#1{\botmarks    \csname\??markingclass#1\endcsname}
194
195\defcsname\??markingfilter\v!first   \endcsname#1{\firstmarks  \csname\??markingclass#1\endcsname}
196\defcsname\??markingfilter\v!last    \endcsname#1{\botmarks    \csname\??markingclass#1\endcsname}
197
198\defcsname\??markingfilter\v!current \endcsname#1{\currentmarks\csname\??markingclass#1\endcsname}
199
200\letcsname\??markingfilter\v!default\expandafter\endcsname
201   \csname\??markingfilter\v!first              \endcsname
202
203% the fetchers are fully expandable: [name][method]
204
205\def\strc_markings_fetch_one#1#2#3%
206  {\ifparameter#1\or
207     \ifconditional\inhibitgetmarking\else
208       \ifcstok{#2}\v!page
209         \markingcommand{#1}{\begincsname\??markingfilter#3\endcsname{#1}}%
210       \else
211         \markingcommand{#1}{\clf_getsynchronizemarking{#1}{#2}}%
212       \fi
213     \fi
214   \fi}
215
216\def\strc_markings_fetch_two#1#2%
217  {\ifparameter#1\or
218     \ifconditional\inhibitgetmarking\else
219       \ifcstok{#2}\v!page
220         \markingcommand{#1}{\begincsname\??markingfilter\v!first\endcsname{#1}}%
221         \markingseparator{#1}%
222         \markingcommand{#1}{\begincsname\??markingfilter\v!last\endcsname{#1}}%
223       \else
224         \markingcommand{#1}{\clf_getsynchronizemarking{#1}\v!first}%
225         \markingseparator{#1}%
226         \markingcommand{#1}{\clf_getsynchronizemarking{#1}\v!last}%
227       \fi
228     \fi
229   \fi}
230
231\def\strc_markings_fetch_all#1#2%
232  {\ifparameter#1\or
233     \ifconditional\inhibitgetmarking\else
234       \ifcstok{#2}\v!page
235         \markingcommand{#1}{\begincsname\??markingfilter\v!previous\endcsname{#1}}%
236         \markingseparator{#1}%
237         \markingcommand{#1}{\begincsname\??markingfilter\v!first\endcsname{#1}}%
238         \markingseparator{#1}%
239         \markingcommand{#1}{\begincsname\??markingfilter\v!last\endcsname{#1}}%
240       \else
241        %\markingcommand{#1}{\begincsname\??markclass:\v!previous\endcsname{#1}}%
242        %\markingseparator{#1}%
243         \markingcommand{#1}{\clf_getsynchronizemarking{#1}\v!first}%
244         \markingseparator{#1}%
245         \markingcommand{#1}{\clf_getsynchronizemarking{#1}\v!last}%
246       \fi
247     \fi
248  \fi}
249
250\permanent\tolerant\def\fetchonemark [#1]#*[#2]{\strc_markings_fetch_one{#1}\v!page{#2}}
251\permanent\tolerant\def\fetchtwomarks      [#1]{\strc_markings_fetch_two{#1}\v!page}
252\permanent\tolerant\def\fetchallmarks      [#1]{\strc_markings_fetch_all{#1}\v!page}
253
254\aliased\let\fetchmark\fetchonemark
255
256% also fully expandable but here we have: [name][range][method]
257
258\permanent\tolerant\def\fetchonemarking [#1]#*[#2]#*[#3]{\strc_markings_fetch_one{#1}{#2}{#3}}
259\permanent\tolerant\def\fetchtwomarkings      [#1]#*[#2]{\strc_markings_fetch_two{#1}{#2}}
260\permanent\tolerant\def\fetchallmarkings      [#1]#*[#2]{\strc_markings_fetch_all{#1}{#2}}
261
262\aliased\let\fetchmarking\fetchonemarking
263
264\permanent\def\markingseparator#1{\namedmarkingparameter{#1}\c!separator}
265\permanent\def\markingcommand  #1{\namedmarkingparameter{#1}\c!filtercommand}
266
267%D Experimental:
268%D
269%D \starttyping
270%D \definemarking[boxmark]
271%D
272%D \setbox0\ruledvbox{
273%D     \marking[boxmark]{tufte} \input tufte \par
274%D     \marking[boxmark]{ward}  \input ward  \par
275%D }
276%D
277%D \synchronizemarking[zerobox][0] \box0
278%D
279%D marks: (\getmarking[boxmark][zerobox][first],\getmarking[boxmark][zerobox][last])
280%D \stoptyping
281
282\protect \endinput
283