strc-lnt.mkvi /size: 10 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-lnt,
3%D        version=2002.05.10,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Line Notes,
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% todo: mkvi #
15
16\writestatus{loading}{ConTeXt Structure Macros / Line Notes}
17
18%D This module loads on top of the footnote and line numbering macros.
19
20\unprotect
21
22\installcorenamespace{linenote}
23
24\let\setuplinenote\setupnote
25
26\newcount\c_strc_linenotes
27\newtoks\everydefinelinenote
28
29\unexpanded\def\definelinenote
30  {\dotripleempty\strc_linenotes_define}
31
32\def\strc_linenotes_define[#1][#2][#3]%
33  {\ifcsname\??linenote#1\endcsname
34     % there might be files that define the default 'linenote'
35     \ifthirdargument
36       \setupnote[#1][#3]%
37     \else\ifsecondargument
38       \setupnote[#1][#2]%
39     \fi\fi
40   \else
41     \ifthirdargument
42       \definenote[#1][#2][#3]%
43     \else\ifsecondargument
44       \definenote[#1][#2]%
45     \else
46       \definenote[#1]%
47     \fi\fi
48     \pushmacro\currentnote
49     \edef\currentnote{#1}
50     \expandafter\let\csname\??linenote\currentnote\expandafter\endcsname\csname\currentnote\endcsname % use copy command
51     \setuevalue        {\currentnote}{\strc_linenotes_direct{\currentnote}}%
52     \setuevalue{\e!start\currentnote}{\strc_linenotes_start {\currentnote}}%
53     \setuevalue{\e!stop \currentnote}{\strc_linenotes_stop                }%
54     \the\everydefinelinenote
55     \popmacro\currentnote
56   \fi}
57
58\unexpanded\def\strc_linenotes_direct#1#2%
59  {\global\advance\c_strc_linenotes\plusone
60   \strc_linenotes_indeed{#1}{\the\c_strc_linenotes}{#2}%
61   \strc_linenotes_traced\empty
62   \normalexpanded{\someline[\the\c_strc_linenotes]}}
63
64\unexpanded\def\strc_linenotes_start#1[#2]#3%
65  {\global\advance\c_strc_linenotes\plusone
66   \keepunwantedspaces
67   \strc_linenotes_indeed{#1}{#2}{#3}%
68   \strc_linenotes_traced{#2}%
69   \startline[#2]}
70
71\unexpanded\def\strc_linenotes_stop[#1]%
72  {\stopline[#1]}
73
74\let\m_page_lines_previous_to  \relax
75\let\m_page_lines_previous_from\relax
76
77\let\m_page_lines_current_to   \relax
78\let\m_page_lines_current_from \relax
79
80\newconditional\c_page_lines_current_to
81\newconditional\c_page_lines_current_from
82
83\installcorenamespace{linenotespreviousfrom}
84\installcorenamespace{linenotespreviousto}
85
86\letvalue\??linenotespreviousfrom\empty
87\letvalue\??linenotespreviousto  \empty
88
89% maybe do this in lua
90
91\def\page_lines_in_from{\in[lr:b:\currentlinenotereference]}
92\def\page_lines_in_to  {\in[lr:e:\currentlinenotereference]}
93
94\unexpanded\def\strc_linenotes_range_normal#1% order
95  {\doifelsereferencefound{lr:b:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_from
96   \ifconditional\c_page_lines_current_from
97      \xdef\m_page_lines_current_from{\currentreferencelinenumber}%
98      \doifelsereferencefound{lr:e:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_to
99      \ifconditional\c_page_lines_current_to
100        \xdef\m_page_lines_current_to{\currentreferencelinenumber}%
101        \page_lines_in_from
102        \ifx\m_page_lines_current_from\m_page_lines_current_to \else
103          \endash
104          \page_lines_in_to
105        \fi
106      \else
107        \page_lines_in_from
108      \fi
109   \else
110     \page_lines_in_from
111   \fi}
112
113\unexpanded\def\strc_linenotes_range_sparse#1% order
114  {\doifelsereferencefound{lr:b:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_from
115   \ifconditional\c_page_lines_current_from
116     \xdef\m_page_lines_current_from{\currentreferencelinenumber}%
117     \doifelsereferencefound{lr:e:\currentlinenotereference}\settrue\setfalse\c_page_lines_current_to
118     \ifconditional\c_page_lines_current_to
119       \xdef\m_page_lines_current_to{\currentreferencelinenumber}%
120       \ifx\m_page_lines_previous_from\m_page_lines_current_from
121         \ifx\m_page_lines_previous_to\m_page_lines_current_to \else
122           \page_lines_in_from
123           \ifx\m_page_lines_current_from\m_page_lines_current_to\else\endash\page_lines_in_to\fi
124         \fi
125       \else
126         \page_lines_in_from
127         \ifx\m_page_lines_current_from\m_page_lines_current_to\else\endash\page_lines_in_to\fi
128       \fi
129     \else
130       \page_lines_in_from
131     \fi
132   \else
133     \ifx\m_page_lines_previous_from\m_page_lines_current_from \else
134       \page_lines_in_from
135     \fi
136   \fi}
137
138\let\currentlinenotereference\empty
139
140\unexpanded\def\strc_linenotes_indeed#1#2#3%
141  {\begingroup
142   % we keep things local so we can use it as regular note too
143   \edef\currentnotation{#1}%
144   \edef\currentlinenotereference{#2}%
145   \xdef\m_page_lines_previous_from{\begincsname\??linenotespreviousfrom\currentnotation\endcsname}%
146   \xdef\m_page_lines_previous_to  {\begincsname\??linenotespreviousto  \currentnotation\endcsname}%
147   \strc_linenotes_check_compression
148   \let\currentnote\currentnotation
149   \letnotationparameter\c!numbercommand\linenotelinenumber% todo: deep hook
150   \letnoteparameter    \c!textcommand  \gobbleoneargument % todo: deep hook
151   \csname\??linenote\currentnotation\endcsname{#3}%
152   \expandafter\glet\csname\??linenotespreviousfrom\currentnotation\endcsname\m_page_lines_current_from
153   \expandafter\glet\csname\??linenotespreviousto  \currentnotation\endcsname\m_page_lines_current_to
154   \endgroup}
155
156% compression
157
158\installcorenamespace{linenotescompressmethod}
159
160% compress=yes|no
161% compressmethod=separator|stopper
162
163\setvalue{\??linenotescompressmethod\v!separator}%
164  {\edef\p_compressseparator{\noteparameter\c!compressseparator}%
165   \scratchskip\noteparameter\c!compressdistance\relax
166   \ifx\p_compressseparator\empty
167     \hskip\scratchskip
168   \else
169     \hskip.5\scratchskip
170     \p_compressseparator
171     \hskip.5\scratchskip
172   \fi}
173
174\setvalue{\??linenotescompressmethod\v!stopper}%
175  {\edef\p_compressstopper{\noteparameter\c!compressstopper}%
176   \scratchskip\noteparameter\c!compressdistance\relax
177   \ifx\p_compressstopper\empty
178     \hskip\scratchskip
179   \else
180     \p_compressstopper
181     \hskip.5\scratchskip
182   \fi}
183
184\setvalue{\??linenotescompressmethod\v!space}%
185  {\hskip\noteparameter\c!compressdistance\relax}
186
187\def\strc_linenotes_check_compression
188%   {\edef\p_linenotes_compress      {\notationparameter\c!compress}%
189%    \edef\p_linenotes_compressmethod{\notationparameter\c!compressmethod}%
190  {\edef\p_linenotes_compress      {\noteparameter\c!compress}%
191   \edef\p_linenotes_compressmethod{\noteparameter\c!compressmethod}%
192   \ifx\p_linenotes_compress\v!yes
193     \let\linenotelinenumber\strc_linenotes_range_sparse
194   \else
195     \let\linenotelinenumber\strc_linenotes_range_normal
196   \fi
197   \ifcsname\??linenotescompressmethod\p_linenotes_compressmethod\endcsname \else
198      \let\p_linenotes_compressmethod\v!space
199   \fi}
200
201\def\strc_linenotes_inbetween % \ifcsname\??linenote\currentnote\expandafter\endcsname
202  {\csname\??linenotescompressmethod\p_linenotes_compressmethod\endcsname}
203
204\def\strc_notes_compress_distance{\emwidth \s!plus .5\emwidth \s!minus .25\emwidth}
205
206\setupnotes
207  [%c\compress=\v!no,
208   \c!compressdistance=\strc_notes_compress_distance,
209   \c!compressseparator=\symbol{\v!compressseparator},
210   \c!compressstopper=\symbol{\v!compressstopper}]
211
212\appendtoks
213    \letnoteparameter\c!inbetween\strc_linenotes_inbetween
214\to \everydefinelinenote
215
216% where to hook this one in? resetcounter has no hook:
217
218\unexpanded\def\doresetlinenotecompression#1% \strc_linenotes_reset_previous
219  {\expandafter\glet\csname\??linenotespreviousfrom#1\endcsname\empty
220   \expandafter\glet\csname\??linenotespreviousto  #1\endcsname\empty}
221
222\definesymbol
223  [\v!compressseparator]
224  [\hbox{\vl\thinspace\vl}] % \space removed
225
226\definesymbol
227  [\v!compressstopper]
228  [,]
229
230% \setupnotations
231%   [%c\compress=\v!no,
232%    \c!compressseparator=\symbol\v!compressseparator]
233
234\let\strc_linenotes_traced\gobbleoneargument
235
236\def\strc_linenotes_traced_indeed#1%
237  {\hpack to \zeropoint
238     {\forgetall
239      \hsize\zeropoint
240      \hss
241      \vpack to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}%
242      {\color[blue]{\vl}}%
243      \vpack to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}%
244      \hss}%
245   \prewordbreak}
246
247\unexpanded\def\tracelinenotes
248  {\let\strc_linenotes_traced\strc_linenotes_traced_indeed}
249
250% We predefine one, namely \type {\linenote} cum suis.
251
252\definelinenote[\v!linenote]
253
254%D Use these when not properly nested:
255
256\let\fromlinenote\startlinenote
257\let\tolinenote  \stoplinenote
258
259% beware: line numbers are added later on so grouping setups is a bad idea
260%
261% \startbuffer[test]
262% \startlinenumbering[100]
263% test \linenote {oeps 1} test test test test test test
264% test \startlinenote [well] {oeps X} test test test test test test
265% test \linenote {oeps 2} test test test test test test
266% test \linenote {oeps 3} test test test test test test
267% test \linenote {oeps 4} test test test test test test
268% test \linenote {oeps 5} test test test test test test
269% test \stoplinenote [well] test test test test test test
270% \stoplinenumbering
271% \stopbuffer
272%
273% \typebuffer[test] \getbuffer[test] \page
274%
275% \startbuffer[setup]
276% \setuplinenumbering
277%   [align=flushleft]
278% \stopbuffer
279%
280% \typebuffer[setup] \getbuffer[setup,test] \page
281%
282% \startbuffer[setup]
283% \setuplinenumbering
284%   [width=4em,
285%    distance=1em,
286%    align=flushright]
287% \stopbuffer
288%
289% \typebuffer[setup] \getbuffer[setup,test] \page
290%
291% \startbuffer[setup]
292% \setuplinenumbering
293%   [width=4em,
294%    align=flushleft]
295% \stopbuffer
296%
297% \typebuffer[setup] \getbuffer[setup,test] \page
298%
299% \startbuffer[setup]
300% \setuplinenumbering
301%   [width=2em,
302%    distance=.5em,
303%    align=middle]
304% \stopbuffer
305%
306% \typebuffer[setup] \getbuffer[setup,test] \page
307%
308% \startbuffer[setup]
309% \setuplinenumbering
310%   [conversion=romannumerals,
311%    start=1,
312%    step=1,
313%    location=text,
314%    style=slanted,
315%    color=blue,
316%    width=1.5em]
317% \stopbuffer
318%
319% \typebuffer[setup] \getbuffer[setup] \startnarrower\getbuffer[test]\stopnarrower \page
320%
321% \startbuffer[setup]
322% \setuplinenumbering
323%   [width=4em,
324%    left=--,
325%    right=--,
326%    align=middle]
327% \stopbuffer
328%
329% \typebuffer[setup] \getbuffer[setup,test] \page
330%
331% \startbuffer[setup-1]
332% \setuplinenumbering
333%   [style=\bfxx,
334%    command=\WatchThis]
335% \stopbuffer
336%
337% \startbuffer[setup-2]
338% \def\WatchThis#1%
339%   {\ifodd\linenumber
340%      \definecolor[linecolor][red]%
341%    \else
342%      \definecolor[linecolor][green]%
343%    \fi
344%    \inframed
345%      [offset=1pt,frame=off,background=color,backgroundcolor=linecolor]
346%      {#1}}
347% \stopbuffer
348%
349% \typebuffer[setup-1,setup-2] \getbuffer[setup-1,setup-2,test] \page
350%
351% \startbuffer[setup-1]
352% \setuplinenumbering
353%   [location=inright,
354%    style=\bfxx,
355%    command=\WatchThis]
356% \stopbuffer
357%
358% \typebuffer[setup-1] \getbuffer[setup-1,setup-2,test] \page
359
360\protect \endinput
361