back-exp.mkxl /size: 14 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=back-exp,
3%D        version=2010.08.22,
4%D          title=\CONTEXT\ Backend Macros,
5%D       subtitle=XML export,
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% see t:/export/todo-fonts.tex for (future) experiment
15
16\writestatus{loading}{ConTeXt Backend Macros / XML export}
17
18\newinteger\tagparcounter
19
20\registerctxluafile{back-exp}        {autosuffix}
21\registerctxluafile{back-exp-imp-tag}{autosuffix}
22\registerctxluafile{back-exp-imp-mth}{autosuffix}
23\registerctxluafile{back-exp-imp-ref}{autosuffix}
24\registerctxluafile{back-exp-imp-fnt}{autosuffix}
25
26%D This is an experimental exporter and a logical follow up on tagging. The
27%D exporter assumes a properly tagged document. Some elements get a couple
28%D of attributes because otherwise rendering information would get lost. In
29%D general we assume that when the \XML\ is converted to \HTML\ some stylesheet
30%D is applied anyway.
31
32\unprotect
33
34% we can replace this by a more generic attributeset mechanism where we bind
35% to any element (needed anyway, see userdata thingies)
36
37\definesystemattribute[taggedpar][public]
38
39\permanent\tolerant\protected\def\setelementexporttag[#1]#*[#2]#*[#3]%
40  {\ifarguments\or\or
41     \clf_settagproperty{#1}{export}{#2}%
42   \or
43     \clf_settagproperty{#1}{#2}{#3}%
44   \fi}
45
46% todo: no need for calls when trialtypesetting
47
48\permanent\def\taggedctxcommand
49  {\iftrialtypesetting
50     \expandafter\gobbleoneargument
51   \else
52     \expandafter\ctxcommand
53   \fi}
54
55\permanent\protected\lettonothing\dotagsetparcounter
56\permanent\protected\lettonothing\doresetparcounter
57
58% Fuzzy:
59
60\appendtoks
61    \doresetparcounter
62\to \everyflushatnextpar
63
64% \appendtoks
65%     \dotagsetparcounter
66% \to \everypar
67
68\prependtoks
69    \dotagsetparcounter
70\to \everypar
71
72% \appendtoks
73%     \dotagsetparcounter
74% \to \neverypar
75
76\prependtoks
77    \dotagsetparcounter
78\to \neverypar
79
80\appendtoks
81    \dotagsetparcounter
82\to \everytabulatepar % tricky, maybe this should be neverypar
83
84\appendtoks
85    \enforced\permanent\protected\def\dotagTABLEcell
86      {\iftrialtypesetting\else
87         \clf_settagtablecell{\tablecellrows}{\tablecellcolumns}{\raggedstatus}%
88       \fi}%
89    % brrr, we need to tag empty cells (unless we start numbering)
90    \enforced\permanent\protected\def\dotagTABLEsignal
91      {\signalcharacter}%
92\to \everyenableelements
93
94\appendtoks
95    \enforced\permanent\protected\def\dotagtabulatecell
96      {\iftrialtypesetting\else
97         \clf_settagtabulatecell\c_tabl_tabulate_align\c_tabl_tabulate_kind
98       \fi}%
99    \enforced\permanent\protected\def\dotagtabulatesignal
100      {\dontleavehmode\signalcharacter\ignorespaces\ignorepars}%
101\to \everyenableelements
102
103\appendtoks
104    \enforced\permanent\protected\def\dotagsynonym
105      {\iftrialtypesetting\else\clf_settagsynonym{\currentsynonymtag}\fi}%
106\to \everyenableelements
107
108\appendtoks
109    \enforced\permanent\protected\def\dotagsorting
110      {\iftrialtypesetting\else\clf_settagsorting{\currentsortingtag}\fi}%
111\to \everyenableelements
112
113\appendtoks % frozen and assumed global per highlight class
114    \enforced\permanent\protected\def\dotagconstruct
115      {\iftrialtypesetting\else
116         \clf_settagconstruct
117           {\currentstartstop}%
118           {\startstopparameter\c!style}%
119           \c_attr_color
120           \ifvmode\plusone\else\zerocount\fi
121           \relax
122       \fi}%
123\to \everyenableelements
124
125\appendtoks % frozen and assumed global per highlight class
126    \enforced\permanent\protected\def\dotaghighlight
127      {\iftrialtypesetting\else
128         \clf_settaghighlight
129           {\currenthighlight}%
130           {\highlightparameter\c!style}
131           \c_attr_color
132           \ifvmode\plusone\else\zerocount\fi
133           \relax
134       \fi}%
135\to \everyenableelements
136
137\mutable\lettonothing\figurecategory
138
139\appendtoks % we can have differently scaled images
140    \enforced\permanent\protected\def\dotagfigure
141      {\iftrialtypesetting\else
142         \clf_settagfigure
143           {\figurefileoriginal}%
144           {\figurefullname}%
145           {\figurefilepage}%
146           {\figurewidth}%
147           {\figureheight}%
148           {\figuredepth}%\relax
149           {\figurelabel}%
150           {\figurecategory}%
151       \fi}%
152\to \everyenableelements
153
154\appendtoks
155    \enforced\permanent\protected\def\dotagcombination
156      {\iftrialtypesetting\else
157         \clf_settagcombination
158            {\combinationparameter\c!nx}%
159            {\combinationparameter\c!ny}%
160       \fi}%
161    \enforced\permanent\protected\def\dotagcombinationpair#1#2%
162      {\iftrialtypesetting\else
163         \clf_settagcombinationpair{#1}{#2}%
164       \fi}%
165\to \everyenableelements
166
167\appendtoks
168    % we don't want a zero one
169    \ifcase\tagparcounter
170      \global\tagparcounter\plusone
171      \c_attr_taggedpar\plusone
172    \fi
173    % as it is also a trigger
174    \enforced\permanent\protected\def\dotagsetparcounter
175      {\global\advanceby\tagparcounter\plusone\c_attr_taggedpar\tagparcounter}%
176    \enforced\permanent\protected\def\doresetparcounter
177      {\c_attr_taggedpar\attributeunsetvalue}%
178\to \everyenableelements
179
180\appendtoks
181    \enforced\permanent\protected\def\dotagsetitemgroup
182      {\iftrialtypesetting\else
183         \clf_settagitemgroup
184           \ifconditional\c_strc_itemgroups_pack     true\else false\fi\relaxedspace
185           \ifconditional\c_strc_itemgroups_continue true\else false\fi\relaxedspace
186           {\currentitemlevel}%
187           {\currentitemgroupsymbol}%
188       \fi}%
189    \enforced\permanent\protected\def\dotagsetitem#1%
190      {\iftrialtypesetting\else
191         \clf_settagitem{#1}%
192       \fi}%
193\to \everyenableelements
194
195%     \appendtoks
196%         \enforced\permanent\protected\def\dotagsetdescription
197%           {\iftrialtypesetting\else
198%              \clf_settagdescription{\currentdescription}\currentdescriptionnumberentry\relax
199%            \fi}%
200%     \to \everyenableelements
201
202\appendtoks
203    \enforced\permanent\protected\def\dotagsetnotation
204      {\iftrialtypesetting\else
205        \clf_settagnotation{\currentnote}\currentnotenumber\relax
206       \fi}%
207\to \everyenableelements
208
209\appendtoks
210    \enforced\permanent\protected\def\dotagsetnotesymbol
211      {\iftrialtypesetting\else
212         \clf_settagnotationsymbol{\currentnote}\currentnotenumber\relax
213       \fi}%
214\to \everyenableelements
215
216\appendtoks
217    \enforced\permanent\protected\def\dotagregisterlocation
218      {\iftrialtypesetting\else
219         \clf_settagregister{\currentregister}\currentregisternumber\relax
220       \fi}%
221\to \everyenableelements
222
223\appendtoks
224    \enforced\permanent\protected\def\dotaglistlocation
225      {\iftrialtypesetting\else
226         \clf_settaglist\currentlistindex\relax
227       \fi}%
228\to \everyenableelements
229
230\appendtoks
231    \enforced\permanent\protected\def\dotagsetdelimitedsymbol#1%
232      {\iftrialtypesetting\else
233         \clf_settagdelimitedsymbol{#1}\relax
234       \fi}%
235\to \everyenableelements
236
237\appendtoks
238    \enforced\permanent\protected\def\dotagsetsubsentencesymbol#1%
239      {\iftrialtypesetting\else
240         \clf_settagsubsentencesymbol{#1}\relax
241       \fi}%
242\to \everyenableelements
243
244\appendtoks
245    \enforced\permanent\protected\def\dotagregisterfloat#1#2%
246      {\iftrialtypesetting\else
247         \clf_settagfloat{#1}{#2}\relax
248       \fi}%
249\to \everyenableelements
250
251\appendtoks
252    \enforced\let\specialfixedspace    \explicitfixedspace
253    \enforced\let\specialobeyedspace   \explicitobeyedspace
254    \enforced\let\specialstretchedspace\explicitstretchedspace
255    \enforced\let\specialcontrolspace  \explicitcontrolspace
256\to \everyenableelements
257
258\appendtoks
259    \enforced\permanent\protected\def\dotagregisterformula#1#2%
260      {\iftrialtypesetting\else
261         \clf_settagformulacontent{#1}{#2}%
262       \fi}%
263\to \everyenableelements
264
265\appendtoks
266    \enforced\permanent\protected\def\dotagmarginanchor#1%
267      {\iftrialtypesetting\else\clf_settagmarginanchor#1\relax\fi}%
268    \enforced\permanent\protected\def\dotagmargintext#1%
269      {\iftrialtypesetting\else\clf_settagmargintext#1\relax\fi}%
270\to \everyenableelements
271
272\appendtoks
273    \enforced\permanent\protected\def\dotagpublication#1#2%
274      {\iftrialtypesetting\else
275         \clf_settagpublication{#1}{#2}\relax
276       \fi}%
277\to \everyenableelements
278
279\appendtoks
280    \enforced\permanent\protected\def\dotagparagraph#1%
281      {\iftrialtypesetting\else
282         \clf_settagparagraph{#1}\relax
283       \fi}%
284\to \everyenableelements
285
286% For more elements, so an extra argument:
287
288\ifdefined\dotagcodepoint \else \aliased\let\dotagcodepoint\gobbletwoarguments \fi
289
290\appendtoks
291    \enforced\permanent\protected\def\dotagcodepoint#1#2%
292      {\iftrialtypesetting\else
293         \clf_settagcodepoint{#1}#2\relax
294       \fi}%
295\to \everyenableelements
296
297% The action: \setupbackend[export=yes] % or filename
298
299% maybe xhtml css settings will move to setupexport
300
301% maybe some day a definer
302
303\installcorenamespace{export}
304
305\installparameterhandler \??export {export}
306\installsetuphandler     \??export {export}
307
308\setupexport
309  [\c!align=\number\raggedstatus, % we pass as string
310   \c!bodyfont=\bodyfontsize,
311   \c!width=\textwidth,
312   \c!title={\directinteractionparameter\c!title},
313   \c!subtitle={\directinteractionparameter\c!subtitle},
314   \c!author={\directinteractionparameter\c!author},
315 % \c!firstpage=, % imagename
316 % \c!lastpage=,  % imagename
317   \c!properties=\v!no, % no: ignore, yes: as attribute, otherwise: use as prefix
318   \c!hyphen=\v!no,
319   \c!svgstyle=,
320   \c!cssfile=,
321   \c!file=]
322
323\resetsystemmode\v!export
324
325\permanent\protected\def\doinitializeexport
326  {\ifempty{\backendparameter\c!export}\else
327      % yes | xml
328      \setuptagging[\c!state=\v!start]%
329      \clf_initializeexport
330      \setsystemmode\v!export
331      \exportingtrue
332      \writestatus\m!backend\empty % so messages will stand out a bit
333      \expand\everyinitializeexport
334      \writestatus\m!backend\empty % so messages will stand out a bit
335      \enforced\glet\doinitializeexport\relax
336   \fi}
337
338\permanent\protected\def\dostartexport
339  {%\glet\dostartexport\relax
340   \lettonothing\currentexport
341   \clf_setupexport
342       % we catch up later
343       align      {\exportparameter\c!align}%
344       bodyfont   {\exportparameter\c!bodyfont}%
345       width      {\exportparameter\c!width}%
346       % till here
347       properties {\exportparameter\c!properties}%
348       hyphen     {\exportparameter\c!hyphen}%
349       title      {\exportparameter\c!title}%
350       subtitle   {\exportparameter\c!subtitle}%
351       author     {\exportparameter\c!author}%
352       firstpage  {\exportparameter\c!firstpage}%
353       lastpage   {\exportparameter\c!lastpage}%
354       svgstyle   {\exportparameter\c!svgstyle}%
355       cssfile    {\exportparameter\c!cssfile}%
356       file       {\exportparameter\c!file}%
357       option     {\exportparameter\c!option}%
358       export     {\backendparameter\c!export}%
359   \relax}
360
361\permanent\protected\def\dostopexport
362  {\enforced\glet\dostopexport\relax
363   \clf_setupexport
364       align      {\exportparameter\c!align}%
365       bodyfont   {\exportparameter\c!bodyfont}%
366       width      {\exportparameter\c!width}%
367   \relax
368   \clf_finishexport}
369
370\appendtoks
371    \doinitializeexport
372\to \everysetupbackend
373
374\appendtoks
375    \ifexporting
376        \dostartexport
377    \fi
378\to \everystarttext
379
380% better (before pdf gets closed, so we can embed), but it needs testing:
381
382\appendtoks
383    \ifexporting
384        \dostopexport
385    \fi
386\to \everystoptext
387
388\appendtoks
389    \ifexporting
390        \dostartexport % in case it is done inside \starttext
391    \fi
392\to \everystartdocument
393
394%D This can replace the older (rather unknown) attachment feature because it
395%D is more immediate (same run). I can also use this then for manuals.
396%D
397%D \setuptagging[state=start] % mandate here
398%D
399%D \starttyping
400%D \startmathexport % [buffer=yes]
401%D     test $ x = 1 + a $ test
402%D \stopmathexport
403%D
404%D \typebuffer
405%D
406%D \startmathexport[buffer=math]
407%D     test $ x = 1 + a^2 $ test
408%D     test $ x = 1 + a $ test
409%D     test $ x = z + \sqrt{a} $ test
410%D \stopmathexport
411%D
412%D \typebuffer[math]
413%D
414%D \startmathexport[filename=foo.xml]
415%D     test $ x = z + \sqrt{a} $ test
416%D \stopmathexport
417%D
418%D \dorecurse{\collectedmath} {\page \collectedmath #1 \page}
419%D \stoptyping
420%D
421%D This one also does buffers and files:
422%D
423%D \starttyping
424%D \startboxexport
425%D     \startparagraph
426%D         \input tufte
427%D     \stopparagraph
428%D     \startitemize
429%D         \startitem item one \stopitem
430%D         \startitem item two \stopitem
431%D     \stopitemize
432%D     \startparagraph
433%D         \input tufte
434%D     \stopparagraph
435%D \stopboxexport
436%D
437%D \typebuffer
438%D \stoptyping
439
440\installcorenamespace {boxexport}
441\installcorenamespace {mathexport}
442
443\installsetuponlycommandhandler \??boxexport  {boxexport}
444\installsetuponlycommandhandler \??mathexport {mathexport}
445
446\permanent\tolerant\protected\def\startboxexport[#S#1]%
447  {\begingroup
448   \ifempty{#1}%
449      \letboxexportparameter\c!buffer\v!yes
450   \orelse\ifhastok={#1}\relax
451      \setupboxexport[#1]%
452   \else
453      \setboxexportparameter\c!buffer{#1}%
454   \fi
455   \setbox\nextbox\vbox\bgroup}
456
457\permanent\protected\def\stopboxexport
458  {\egroup
459   \clf_exportbox \nextbox
460     {\boxexportparameter\c!file}%
461     {\boxexportparameter\c!buffer}%
462   \endgroup}
463
464\permanent\tolerant\protected\def\startmathexport[#S#1]%
465  {\begingroup
466   \ifempty{#1}%
467      \letmathexportparameter\c!buffer\v!yes
468   \orelse\ifhastok={#1}\relax
469      \setupmathexport[#1]%
470   \else
471      \setmathexportparameter\c!buffer{#1}%
472   \fi
473   \clf_startcollectingmath}
474
475\permanent\protected\def\stopmathexport
476  {\clf_stopcollectingmath
477   \clf_processcollectedmath
478     {\mathexportparameter\c!file}%
479     {\mathexportparameter\c!buffer}%
480     {\mathexportparameter\c!n}%
481     {\mathexportparameter\c!option}%
482   \endgroup}
483
484\permanent\tolerant\protected\def\savemathexport[#S#1]%
485  {\begingroup
486   \setupmathexport[#1]%
487   \clf_processcollectedmath
488     {\mathexportparameter\c!file}%
489     {\mathexportparameter\c!buffer}%
490     {\mathexportparameter\c!n}%
491     {\mathexportparameter\c!option}%
492   \endgroup}
493
494% Defined at the \LUA\ end:
495%
496% \the\collectedmath : number of snippets
497% \collectedmath n   : specific snippet
498
499% \startluacode
500%     function commands.doifelsesimplecollectedmath()
501%         commands.doifelse(string.find(
502%             buffers.getcontent("test"),
503%             "<math.->%s*<m[nio]>[^<>]+</m[nio]>%s*</math>")
504%         )
505%     end
506% \stopluacode
507%
508% \dorecurse {\collectedmath} {
509%     \savemathexport[buffer=test,n=#1]
510%     \ctxlua{commands.doifelsesimplecollectedmath()} {
511%     } {
512%         \startsubsubsubject[title={math blob #1}]
513%             \typebuffer[test]
514%         \stopsubsubsubject
515%     }
516% }
517
518\protect \endinput
519