buff-ini.mkxl /size: 9824 b    last modification: 2023-12-21 09:44
1%D \module
2%D   [       file=buff-ini,
3%D        version=2011.11.22, % previous big effort 2000.01.05,
4%D          title=\CONTEXT\ Buffer Macros,
5%D       subtitle=Buffers,
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 Buffer Macros / Buffers}
15
16\registerctxluafile{buff-ini}{autosuffix}
17
18\unprotect
19
20%D There have been several iterations in \MKIV\ but here we only show the currently
21%D used one. One can always look back (and maybe learn some). It will never look
22%D pretty and never be efficient but it has served us for ages (conceptually it's
23%D as in \MKII).
24
25\mutable\lettonothing\currentbuffer
26
27% \doifelsebuffer      {#1} % expandable
28% \doifelsebufferempty {#1} % non expandable
29
30\aliased\let\doifbufferelse\doifelsebuffer
31
32\permanent\tolerant\protected\def\resetbuffer[#1]{\clf_erasebuffer{#1}} % todo: use public implementor
33
34\permanent\protected\defcsname\e!start\v!buffer\endcsname
35  {\begingroup % (3)
36   \obeylines
37   \buff_start}
38
39\tolerant\def\buff_start[#1]#*[#2]%
40  {\buff_start_indeed{}{#1}{\e!start\v!buffer}{\e!stop\v!buffer}}
41
42\def\buff_start_indeed#1#2#3#4%
43  {\normalexpanded{\buff_pickup
44     {#2}%
45     {#3}%
46     {#4}%
47     {}%
48     {\buff_stop{#4}}%
49     \ifcstok{\namedbufferparameter{#1}\c!strip}\v!no\zerocount\else\plusone\fi}}
50
51\permanent\protected\def\grabbufferdatadirect % name start stop
52  {\begingroup % (6)
53   \buff_start_indeed\empty}
54
55\permanent\protected\def\grabbufferdata % was: \dostartbuffer
56  {\begingroup % (4)
57   \obeylines
58   \buff_grab_direct}
59
60\tolerant\def\buff_grab_direct[#1]#*[#2]#*[#3]#*[#4]% [category] [name] [start] [stop]
61  {\ifnum\lastarguments=\plusfour
62     \expandafter\buff_start_indeed
63   \else
64     \expandafter\buff_start_indeed_default
65   \fi{#1}{#2}{#3}{#4}}
66
67\def\buff_start_indeed_default#1#2#3#4{\buff_start_indeed\empty{#1}{#2}{#3}}
68
69\let\buff_finish\relax
70%let\buff_gobble\relax
71
72\protected\def\buff_pickup#1#2#3#4#5#6% name, startsequence, stopsequence, before, after, undent
73  {\begingroup % (1)
74   #4%
75   \begingroup % (2)
76   \scratchcounterone\catcodetable
77   \scratchcountertwo#6\relax
78   \clf_erasebuffer{#1}%
79   \setcatcodetable\vrbcatcodes
80   \protected\def\buff_finish
81     {\endgroup % (1)
82      \endgroup % (2)
83      #5}%
84   % todo: we need to skip the first lineending which is an active character
85   % but sometimes we have something different ... this is a side effect of
86   % checking for optional arguments i.e. the next token is already tokenized
87   % and for that reason we had the \relax as well as the \string
88   \clf_pickupbuffer
89     {#1}%
90     {#2}%
91     {#3}%
92   % {\string\dofinishpickupbuffer}%
93     \buff_finish
94   % \ifnum#6=\plusone\s!true\else\s!false\fi
95   % \expandafter\relax\string} % dirty trick
96     \scratchcounterone
97     % better than \string but still a dirty trick to avoid \par mess in blocks
98     \expandafter\scratchcountertwo\detokenized} % the bare token (so not \detokened !)
99
100\protected\def\buff_stop#1%
101  {\endgroup % (3 & 4 & 5 & 6)
102   \begincsname#1\endcsname}
103
104\permanent\protected\lettonothing\endbuffer
105
106\permanent\tolerant\protected\def\setbuffer[#1]#:#2\endbuffer % seldom used so we just pass #2
107  {\clf_assignbuffer{#1}{\detokenize{#2}}\catcodetable\relax}
108
109% Beware, never adapt the global buffer settings, actually we might introduce
110% a broken parent chain for this purpose but on the other hand it's not that
111% different from framed cum suis.
112
113\installcorenamespace{buffer}
114
115\installcommandhandler \??buffer {buffer} \??buffer
116
117\setupbuffer
118  [\c!before=,
119   \c!after=,
120   \c!define=\v!yes]
121
122\newinteger\c_buff_n_of_defined
123
124\mutable\let\currentdefinedbuffer\s!dummy
125
126\appendtoks
127    \global\advanceby\c_buff_n_of_defined\plusone
128    \setexpandedbufferparameter\c!number{\the\c_buff_n_of_defined}%
129    \cdef\currentdefinedbuffer{def-\the\c_buff_n_of_defined}%
130    \ifcstok{\bufferparameter\c!define}\v!yes
131      \frozen\instance\protected\edefcsname\e!start\currentbuffer\endcsname
132        {\buff_start_defined{\currentbuffer}{\currentdefinedbuffer}{\e!start\currentbuffer}{\e!stop\currentbuffer}}%
133      \frozen\instance\protected\edefcsname\e!get  \currentbuffer\endcsname
134        {\buff_get_stored   {\currentbuffer}{\currentdefinedbuffer}}%
135    \fi
136\to \everydefinebuffer
137
138\protected\def\buff_start_defined
139  {\begingroup % (5)
140   \buff_start_indeed}
141
142\permanent\def\thebuffernumber #1{\namedbufferparameter{#1}\c!number}
143\permanent\def\thedefinedbuffer#1{def-\namedbufferparameter{#1}\c!number}
144
145\permanent\def\getbufferdata[#1]% expandable
146  {\clf_getbuffer{#1}}
147
148\permanent\tolerant\protected\def\getbuffer[#1]% [namelist]
149  {\namedbufferparameter\empty\c!before\relax
150   \clf_getbuffer{#1}%
151   \namedbufferparameter\empty\c!after\relax}
152
153\protected\def\buff_get_stored#1#2%
154  {\namedbufferparameter{#1}\c!before\relax
155   \clf_getbuffer{#2}%
156   \namedbufferparameter{#1}\c!after\relax}
157
158\aliased\let\rawbuffer\clf_getbuffer % expandable
159
160\permanent\protected\def\getdefinedbuffer[#1]%
161  {\buff_get_stored{#1}{\thedefinedbuffer{#1}}}%
162
163% We had this:
164%
165% \permanent\tolerant\protected\def\inlinebuffer[#1]% [name]
166%   {\ifempty{#1}
167%      \buff_get_stored_inline_indeed\empty
168%    \else
169%      \processcommalist[#1]\buff_get_stored_inline_indeed
170%    \fi}
171%
172% \protected\def\buff_get_stored_inline_indeed#1%
173%   {\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces}
174%
175% but it makes no sense to ignore spaces in between and we now do the
176% list at the \LUA\ end anyway:
177
178\permanent\tolerant\protected\def\inlinebuffer[#1]% [name]
179  {\ignorespaces\clf_getbuffer{#1}\removeunwantedspaces}
180
181\definebuffer
182  [\v!hiding]
183
184\setupbuffer
185  [\v!hiding]
186  [\c!before=,
187   \c!after=]
188
189%D \starttyping
190%D \startbuffer[x]
191%D x y z
192%D \stopbuffer
193%D
194%D \savebuffer[x]      [temp]     % gets name: jobname-temp.tmp
195%D \savebufferinfile[x][temp.log] % gets name: temp.log
196%D \stoptyping
197
198\installcorenamespace{savebuffer}
199\installcorenamespace{savebuffercounter}
200
201\installcommandhandler \??savebuffer {savebuffer} \??savebuffer
202
203\setupsavebuffer
204  [\c!list=,
205   \c!file=,
206   \c!directory=,
207   \c!prefix=\v!yes]
208
209\permanent\tolerant\protected\def\savebuffer[#S#1]#*[#2]%
210  {\begingroup
211   \ifhastok={#1}%
212     \setupcurrentsavebuffer[#1]%
213   \else
214     \setupcurrentsavebuffer[\c!list={#1},\c!file=#2]%
215   \fi
216   \clf_savebuffer % will become key/value
217     {\savebufferparameter\c!list}%
218     {\savebufferparameter\c!file}%
219     {\savebufferparameter\c!prefix}%
220     {\savebufferparameter\c!option}%
221     {\savebufferparameter\c!directory}%
222   \endgroup}
223
224%D \starttyping
225%D \definesavebuffer[slide]
226%D
227%D \starttext
228%D     \startslide
229%D         \starttext
230%D     \stopslide
231%D     \startslide
232%D         slide 1
233%D     \stopslide
234%D     text 1 \par
235%D     \startslide
236%D         slide 2
237%D     \stopslide
238%D     text 2 \par
239%D     \startslide
240%D         \stoptext
241%D     \stopslide
242%D \stoptext
243%D \stoptyping
244
245% We can keep the counter at the lua end and explicitly reset it when we
246% save.
247
248\appendtoks
249    \ifcsname\e!stop\currentsavebuffer\endcsname\else
250      \definebuffer[\currentsavebuffer]%
251      \expandafter\newinteger\csname\??savebuffercounter\currentsavebuffer\endcsname
252      \protected\edefcsname\e!stop\currentsavebuffer\endcsname{\buff_stop_save_buffer{\currentsavebuffer}}%
253      \setsavebufferparameter\c!file{\currentsavebuffer.tex}%
254    \fi
255\to \everydefinesavebuffer
256
257\protected\def\buff_stop_save_buffer#1%
258  {\cdef\currentsavebuffer{#1}%
259   \global\advanceby\csname\??savebuffercounter\currentsavebuffer\endcsname\plusone
260   \clf_savebuffer % will become key/value
261     {\thedefinedbuffer{\currentsavebuffer}}%
262     {\savebufferparameter\c!file}%
263     {\savebufferparameter\c!prefix}%
264     {\ifnum\csname\??savebuffercounter\currentsavebuffer\endcsname>\plusone\v!append\fi}%
265     {\savebufferparameter\c!directory}}
266
267%D Experimental: no expansion of commands in buffer!
268
269% \startbuffer[what]
270%     context("WHAT")
271% \stopbuffer
272% \startbuffer
273%     context("JOBNAME")
274% \stopbuffer
275%
276% \ctxluabuffer[what] \ctxluabuffer
277
278\permanent\tolerant\protected\def\processTEXbuffer[#1]#;#=% keep case, maybe also lower
279  {\pushcatcodetable
280   \catcodetable\ctxcatcodes % \setcatcodetable
281   \clf_getbuffer{#1#2}%
282   \popcatcodetable}
283
284\permanent\tolerant\protected\def\ctxluabuffer[#1]#;#={\clf_getbufferctxlua{#1#2}} % todo: use public implementor
285\permanent\tolerant\protected\def\mkvibuffer  [#1]#;#={\clf_getbuffermkvi  {#1#2}} % todo: use public implementor
286\permanent\tolerant\protected\def\texbuffer   [#1]#;#={\clf_getbuffertex   {#1#2}} % todo: use public implementor
287
288% maybe still used elsewhere
289
290% \aliased\doprocesstexbuffer\mkvibuffer
291
292\aliased\let\dostartbuffer\grabbufferdata % for old times sake, this will go away
293
294% low level helper (for math manual):
295
296% \showboxinbuffer{temp}<boxnumber><detail> % defined in lua, detail cf \shownodedetails 0|1|2
297
298%D \starttyping
299%D \setbox\scratchbox\hbox{$fff$}
300%D \showboxinbuffer{temp}\scratchbox\plusone
301%D \typebuffer[temp][option=TEX]
302%D \stoptyping
303%D
304%D More extensive multistep cases can do this:
305%D
306%D \starttyping
307%D \pushlogfile{oeps-1.txt}
308%D \setbox0\hbox{A}\showbox0
309%D \pushlogfile{oeps-2.txt}
310%D \setbox0\hbox{B}\showbox0
311%D \poplogfile
312%D \setbox0\hbox{C}\showbox0
313%D \poplogfile
314%D
315%D % \resetlogfile{oeps-1.txt}
316%D \pushlogfile{oeps-1.txt}
317%D \setbox0\hbox{A}\showbox0
318%D \pushlogfile{oeps-2.txt}
319%D \setbox0\hbox{B}\showbox0
320%D \poplogfile
321%D \setbox0\hbox{C}\showbox0
322%D \poplogfile
323%D \stoptyping
324%D
325%D But in the end that was overkill and we don't really need a stepwise verbatim
326%D because we need to add comments in between anyway.
327
328\protect \endinput
329