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