strc-tag.mkiv /size: 19 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=strc-tag,
3%D        version=2010.07.16,
4%D          title=\CONTEXT\ Structure Macros,
5%D       subtitle=Tags,
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% labels: no language needed
15% key/values and other names might change (and probably will)
16
17\writestatus{loading}{ConTeXt Structure Macros / Tags}
18
19\registerctxluafile{strc-tag}{}
20
21\unprotect
22
23%D Eventually these labels will either move to the modules where they're used, or
24%D they will en dup in mult-tag.
25
26\definetagconstant{document}               % Div
27
28\definetagconstant{division}               % Div
29\definetagconstant{paragraph}              % P
30\definetagconstant{p}                      % P
31\definetagconstant{construct}              % Span
32\definetagconstant{highlight}              % Span
33
34\definetagconstant{section}                % Sect
35\definetagconstant{sectioncaption}         % Div
36\definetagconstant{sectiontitle}           % H
37\definetagconstant{sectionnumber}          % H
38\definetagconstant{sectioncontent}         % Div
39
40\definetagconstant{itemgroup}              % L
41\definetagconstant{item}                   % Li
42\definetagconstant{itemtag}                % Lbl
43\definetagconstant{itemcontent}            % LBody
44\definetagconstant{itemhead}               % Div
45\definetagconstant{itembody}               % Div
46
47\definetagconstant{description}            % Li
48\definetagconstant{descriptiontag}         % Lbl
49\definetagconstant{descriptioncontent}     % LBody
50\definetagconstant{descriptionsymbol}      % Span
51
52\aliastagconstant{construction}       {description}
53\aliastagconstant{constructiontag}    {descriptiontag}
54\aliastagconstant{constructioncontent}{descriptioncontent}
55\aliastagconstant{constructionsymbol} {descriptionsymbol}
56
57\definetagconstant{verbatimblock}          % Code
58\definetagconstant{verbatimlines}          % Code
59\definetagconstant{verbatimline}           % Code
60\definetagconstant{verbatim}               % Code
61
62\definetagconstant{lines}                  % Code
63\definetagconstant{line}                   % Code
64\definetagconstant{linenumber}             % Span
65
66\definetagconstant{sorting}                % Span
67\definetagconstant{synonym}                % Span
68
69\definetagconstant{register}               % Div
70\definetagconstant{registerlocation}       % Span
71\definetagconstant{registersection}        % Div
72\definetagconstant{registertag}            % Span
73\definetagconstant{registerentries}        % Div
74\definetagconstant{registerentry}          % Span
75\definetagconstant{registercontent}        % Span
76\definetagconstant{registersee}            % Span
77\definetagconstant{registerpages}          % Span
78\definetagconstant{registerpage}           % Span
79\definetagconstant{registerpagerange}      % Span
80\definetagconstant{registerfrompage}       % Span
81\definetagconstant{registertopage}         % Span
82\definetagconstant{registerseparator}      % Span
83
84\definetagconstant{table}                  % Table
85\definetagconstant{tablerow}               % TR
86\definetagconstant{tablecell}              % TD
87\definetagconstant{tableheadcell}          % TH
88\definetagconstant{tablehead}              % THEAD
89\definetagconstant{tablebody}              % TBODY
90\definetagconstant{tablefoot}              % TFOOT
91
92\definetagconstant{tabulate}               % Table
93\definetagconstant{tabulaterow}            % TR
94\definetagconstant{tabulatecell}           % TD
95\definetagconstant{tabulateheadcell}       % TH
96\definetagconstant{tabulatehead}           % THEAD
97\definetagconstant{tabulatebody}           % TBODY
98\definetagconstant{tabulatefoot}           % TFOOT
99
100\definetagconstant{math}                   % math
101\definetagconstant{mtable}                 % Table
102\definetagconstant{mtr}                    % TR
103\definetagconstant{mtd}                    % TD
104\definetagconstant{maction}                %
105\definetagconstant{mstacker}
106\definetagconstant{mstackertop}
107\definetagconstant{mstackermid}
108\definetagconstant{mstackerbot}
109
110\aliastagconstant{mtablerow} {mtr}
111\aliastagconstant{mtablecell}{mtd}
112
113\definetagconstant{munderover}             % special cases
114\definetagconstant{munder}                 % special cases
115\definetagconstant{mover}                  % special cases
116
117\definetagconstant{list}                   % TOC
118\definetagconstant{listitem}               % TOCI
119\definetagconstant{listtag}                % Lbl
120\definetagconstant{listcontent}            % P
121\definetagconstant{listdata}               % P
122\definetagconstant{listpage}               % Reference
123\definetagconstant{listtext}               % Span
124
125\definetagconstant{delimited}              % BlockQuote
126%definetagconstant{delimited}              % Quote
127\definetagconstant{delimitedsymbol}        % Span
128\definetagconstant{delimitedcontent}       % Span
129
130\aliastagconstant{delimitedblock}{delimited}
131
132\definetagconstant{subsentence}            % Span
133\definetagconstant{subsentencecontent}     % Span
134\definetagconstant{subsentencesymbol}      % Span
135
136\definetagconstant{float}                  % Div
137\definetagconstant{floatcaption}           % Caption
138\definetagconstant{floatlabel}             % Span
139\definetagconstant{floattext}              % Span
140\definetagconstant{floatnumber}            % Span
141\definetagconstant{floatcontent}           % P
142
143\definetagconstant{image}                  % P
144
145\definetagconstant{mpgraphic}              % P
146
147\definetagconstant{formulaset}             % Div
148\definetagconstant{formula}                % Div
149\definetagconstant{formulacaption}         % Span
150\definetagconstant{formulalabel}           % Span
151\definetagconstant{formulanumber}          % P
152\definetagconstant{formulacontent}         % P
153\definetagconstant{subformula}             % Div
154
155\definetagconstant{link}                   % Link
156\definetagconstant{reference}              % Span
157
158\definetagconstant{margintext}             % Span
159\definetagconstant{margintextblock}        % Div
160\definetagconstant{marginanchor}           % Span
161
162% we might opt for verbose variants so this is experimental:
163
164\definetagconstant{label}                  % Span
165\definetagconstant{number}                 % Span
166
167\definetagconstant{ignore}                 % Span
168\definetagconstant{private}                % Span
169
170\definetagconstant{mid}                    % Span
171\definetagconstant{sub}                    % Span
172\definetagconstant{sup}                    % Span
173\definetagconstant{subsup}                 % Span
174
175\definetagconstant{unit}                   % Span
176\definetagconstant{quantity}               % Span
177%definetagconstant{number}                 % Span
178
179\definetagconstant{combination}            % Span
180\definetagconstant{combinationpair}        % Span
181\definetagconstant{combinationcontent}     % Span
182\definetagconstant{combinationcaption}     % Span
183
184\definetagconstant{publications}           % Span
185\definetagconstant{publication}            % Span
186\definetagconstant{pubfld}                 % Span
187
188\definetagconstant{block}                  % Div
189\definetagconstant{userdata}               % Div
190
191% \setuptaglabeltext
192%   [en]
193%   [\t!document=document]
194
195% the real code
196
197\definesystemattribute[tagged][public]
198\definesystemattribute[image] [public]
199
200\unexpanded\def\setelementbackendtag{\dodoubleargument\strc_tags_set_backend}
201\unexpanded\def\setelementnature    {\dodoubleargument\strc_tags_set_nature}
202
203\def\strc_tags_set_backend[#1][#2]{\clf_settagproperty_b{#1}{#2}} % todo: ignore when no export
204\def\strc_tags_set_nature [#1][#2]{\clf_settagproperty_n{#1}{#2}} % todo: ignore when no export
205
206\unexpanded\def\strc_tags_set_aspect_nop#1#2{}
207\unexpanded\def\strc_tags_set_aspect_yes#1#2{\clf_settagaspect{#1}{#2}} % todo: ignore when no export / also \let
208
209\unexpanded\def\ignoretagsinexport[#1]%
210  {\clf_ignoretagsinexport{#1}}
211
212\installcorenamespace{tagging}
213
214\installsetuponlycommandhandler \??tagging {tagging}
215
216% it makes no sense to have labels ... maybe some day as a last 'replace' in the export
217% which might be more efficient then ... okay, we now cannot overload but who cares
218
219\unexpanded\def\strc_tags_element_start_yes{\dodoubleempty\strc_tags_element_start_yes_indeed}
220\unexpanded\def\strc_tags_element_start_nop{\dodoubleempty\strc_tags_element_start_nop_indeed}
221
222\unexpanded\def\strc_tags_element_start_yes_indeed
223  {\iftrialtypesetting
224     \expandafter\strc_tags_element_start_yes_indeed_nop
225   \else
226     \expandafter\strc_tags_element_start_yes_indeed_yes
227   \fi}
228
229\unexpanded\def\strc_tags_element_start_yes_indeed_nop[#1][#2]%
230  {}
231
232\unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]%
233  {\clf_starttag_u{#1}{#2}}
234
235\unexpanded\def\strc_tags_element_stop_yes
236  {\iftrialtypesetting
237     \expandafter\strc_tags_element_stop_yes_indeed_nop
238   \else
239     \expandafter\strc_tags_element_stop_yes_indeed_yes
240   \fi}
241
242\unexpanded\def\strc_tags_element_stop_nop
243  {}
244
245\unexpanded\def\strc_tags_element_stop_yes_indeed_nop
246  {}
247
248\unexpanded\def\strc_tags_element_stop_yes_indeed_yes
249  {\clf_stoptag}
250
251\let\strc_tags_element_start_nop_indeed\strc_tags_element_start_yes_indeed_nop
252\let\strc_tags_element_stop_nop_indeed \strc_tags_element_stop_yes_indeed_nop
253
254\def\strc_tags_report_hyphen#1%
255  {\writestatus\m!languages{setting #1 to U+00AD}}
256
257\unexpanded\def\strc_tags_patch_hyphen
258  {% for the moment here
259   \ifnum\languageparameter\s!lefthyphenchar>\zerocount
260     \setuplanguage[\s!default][\s!lefthyphenchar="AD]%
261     \strc_tags_report_hyphen\s!lefthyphenchar
262   \fi
263   \ifnum\languageparameter\s!righthyphenchar>\zerocount
264     \setuplanguage[\s!default][\s!righthyphenchar="AD]%
265     \strc_tags_report_hyphen\s!righthyphenchar
266   \fi
267   \let\strc_tags_report_hyphen\gobbleoneargument}
268
269\unexpanded\def\strc_tags_enable_elements
270  {\strc_tags_patch_hyphen
271   \let\startelement\strc_tags_element_start_yes
272   \let\stopelement \strc_tags_element_stop_yes
273   \let\dosettagproperty\strc_tags_set_aspect_yes}
274
275\unexpanded\def\strc_tags_disable_elements
276  {\let\startelement\strc_tags_element_start_nop
277   \let\stopelement \strc_tags_element_stop_nop
278   \let\dosettagproperty\strc_tags_set_aspect_nop}
279
280% beware: making these unexpanded spoils tables (noalign problem)
281
282\def\strc_tags_enabled_start_no_detail
283  {\iftrialtypesetting
284     \expandafter\strc_tags_start_nop_no_detail
285   \else
286     \expandafter\strc_tags_start_yes_no_detail
287   \fi}
288
289\def\strc_tags_enabled_start_detail
290  {\iftrialtypesetting
291     \expandafter\strc_tags_start_nop_detail
292   \else
293     \expandafter\strc_tags_start_yes_detail
294   \fi}
295
296\def\strc_tags_enabled_start_chained
297  {\iftrialtypesetting
298     \expandafter\strc_tags_start_nop_chained
299   \else
300     \expandafter\strc_tags_start_yes_chained
301   \fi}
302
303\def\strc_tags_enabled_stop
304  {\iftrialtypesetting
305     \expandafter\strc_tags_stop_nop
306   \else
307     \expandafter\strc_tags_stop_yes
308  \fi}
309
310\def\strc_tags_start_yes_no_detail    #1{\clf_starttag{#1}}
311\def\strc_tags_start_yes_detail     #1#2{\clf_starttag_d{#1}{#2}}
312\def\strc_tags_start_yes_chained  #1#2#3{\clf_starttag_c{#1}{#2}{\getcurrentparentchain#3{#2}}}
313\def\strc_tags_stop_yes                 {\clf_stoptag}
314
315\let\strc_tags_start_nop_no_detail\gobbleoneargument
316\let\strc_tags_start_nop_detail   \gobbletwoarguments
317\let\strc_tags_start_nop_chained  \gobblethreearguments
318\let\strc_tags_stop_nop           \donothing
319
320\def\strc_tags_start_yes_ignore{\clf_starttag{\t!ignore}}
321\let\strc_tags_stop_yes_ignore \strc_tags_stop_yes
322\let\strc_tags_start_nop_ignore\donothing
323\let\strc_tags_stop_nop_ignore \donothing
324
325% more efficient:
326
327% \dostarttagged         % {tag} {detail}
328% \dostarttaggedchained  % {tag} {detail} \??hash
329% \dostarttaggednodetail % {tag}
330
331\newconditional\c_strc_tags_enabled
332
333\let\dotaggedplaceholder\empty
334
335\chardef\strc_tags_placeholder_char\zerocount % "FFFC
336
337\unexpanded\def\strc_tags_enable_indeed
338  {\let\dotaggedplaceholder  \strc_tags_placeholder_char
339   \let\dostarttagged        \strc_tags_enabled_start_detail
340   \let\dostarttaggednodetail\strc_tags_enabled_start_no_detail
341   \let\dostarttaggedchained \strc_tags_enabled_start_chained
342   \let\dostoptagged         \strc_tags_enabled_stop
343   \let\dostartignoretagging \strc_tags_start_yes_ignore
344   \let\dostopignoretagging  \strc_tags_stop_yes_ignore}
345
346\unexpanded\def\strc_tags_enable
347  {% once enable one is toast
348   \global\settrue\c_strc_tags_enabled
349   % and gets:
350   \strc_tags_enable_indeed}
351
352\unexpanded\def\strc_tags_disable
353  {\ifconditional\c_strc_tags_enabled
354     % so now all are artifacts
355     \let\dotaggedplaceholder  \strc_tags_placeholder_char
356     \let\dostarttagged        \strc_tags_start_nop_detail
357     \let\dostarttaggednodetail\strc_tags_start_nop_no_detail
358     \let\dostarttaggedchained \strc_tags_start_nop_chained
359     \let\dostoptagged         \strc_tags_stop_nop_ignore
360   \else
361     % initial
362     \let\dotaggedplaceholder  \empty
363     \let\dostarttagged        \strc_tags_start_nop_detail
364     \let\dostarttaggednodetail\strc_tags_start_nop_no_detail
365     \let\dostarttaggedchained \strc_tags_start_nop_chained
366     \let\dostoptagged         \strc_tags_stop_nop_ignore
367     \let\dostartignoretagging \strc_tags_start_nop_ignore
368     \let\dostopignoretagging  \strc_tags_stop_nop_ignore
369   \fi}
370
371% for luigi (beware: fully expandable):
372
373\def\strc_tags_get_element_tag_yes{\clf_getelementtag}
374\let\strc_tags_get_element_tag_nop\donothing
375
376\unexpanded\def\strc_tags_setup_element_user_properties_yes
377  {\dodoubleempty\strc_tags_setup_element_user_properties_indeed}
378
379\unexpanded\def\strc_tags_setup_element_user_properties_nop
380  {\dodoubleempty\strc_tags_setup_element_user_properties_indeed_nop}
381
382\def\strc_tags_setup_element_user_properties_indeed
383  {\iftrialtypesetting
384     \expandafter\strc_tags_setup_element_user_properties_indeed_nop
385   \else
386     \expandafter\strc_tags_setup_element_user_properties_indeed_yes
387   \fi}
388
389\def\strc_tags_setup_element_user_properties_indeed_nop[#1][#2]{}
390\def\strc_tags_setup_element_user_properties_indeed_yes[#1][#2]{\clf_setelementuserproperties{#1}{#2}}
391
392\unexpanded\def\strc_tags_enable_properties
393  {\let\getelementtag             \strc_tags_get_element_tag_yes
394   \let\setupelementuserproperties\strc_tags_setup_element_user_properties_yes}
395
396\unexpanded\def\strc_tags_disable_properties
397  {\let\getelementtag             \strc_tags_get_element_tag_nop
398   \let\setupelementuserproperties\strc_tags_setup_element_user_properties_nop}
399
400%D The triggers:
401
402\newtoks\everyenableelements
403\newtoks\everydisableelements
404
405\appendtoks
406    \strc_tags_enable_elements
407    \strc_tags_enable_properties
408    \doifelse{\taggingparameter\c!method}\v!auto\strc_tags_enable\strc_tags_disable
409\to \everyenableelements
410
411\appendtoks
412    \strc_tags_disable_elements
413    \strc_tags_disable_properties
414    \strc_tags_disable
415\to \everydisableelements
416
417\appendtoks
418   \doifelse{\taggingparameter\c!state}\v!start{\the\everyenableelements}{\the\everydisableelements}%
419\to \everysetuptagging
420
421\unexpanded\def\forgettagging
422  {\c_attr_tagged\attributeunsetvalue}
423
424\setuptagging
425  [\c!state=\v!stop,
426   \c!method=\v!auto]
427
428% \unexpanded\def\startparagraph
429%   {\dostarttagged\t!paragraph\empty}
430%
431% \unexpanded\def\stopparagraph
432%   {% \removeunwantedspaces % yes or no
433%    \dostoptagged
434%    \par}
435
436% Cf suggestion by Wolfgang we now have named paragraphs. Watch out, the content
437% is grouped but only when we have an instance.
438%
439% \defineparagraph[red] [color=red]
440% \defineparagraph[bold][style=bold]
441%
442% \startparagraph       \input ward \stopparagraph
443% \startparagraph[red]  \input ward \stopparagraph
444% \startparagraph[bold] \input ward \stopparagraph
445
446\installcorenamespace               {paragraph}
447\installcommandhandler \??paragraph {paragraph} \??paragraph
448
449\setupparagraph % someday maybe also strut (beg/end) and align
450  [\c!color=,
451   \c!style=]
452
453\unexpanded\def\startparagraph
454  {\dodoubleempty\paragraph_start}
455
456\def\paragraph_start
457  {\endgraf % we end before the group
458   \begingroup
459   \iffirstargument
460     \ifsecondargument
461       \doubleexpandafter\paragraph_start_two
462     \else
463       \doubleexpandafter\paragraph_start_one
464     \fi
465   \else
466     \expandafter\paragraph_start_zero
467   \fi}
468
469\def\paragraph_start_two[#1][#2]%
470  {\edef\currentparagraph{#1}%
471   \setupcurrentparagraph[#2]%
472   \paragraph_start_indeed}
473
474\def\paragraph_start_one[#1][#2]%
475  {\doifelseassignment{#1}
476     {\let\currentparagraph\empty
477      \setupcurrentparagraph[#1]}
478     {\edef\currentparagraph{#1}}%
479   \paragraph_start_indeed}
480
481\def\paragraph_start_zero[#1][#2]%
482  {\let\currentparagraph\empty
483   \paragraph_start_indeed}
484
485\ifdefined\dotagparagraph \else \let\dotagparagraph \gobbleoneargument \fi
486
487\def\paragraph_start_indeed
488  {\useparagraphstyleandcolor\c!style\c!color
489   \usealignparameter\paragraphparameter
490   \usesetupsparameter\paragraphparameter
491   \dostarttagged\t!paragraph\currentparagraph
492   \dotagparagraph{\paragraphparameter\c!align}}
493
494\unexpanded\def\stopparagraph
495  {\dostoptagged
496   \endgraf % we end inside the group
497   \endgroup}
498
499\let\startpar\startparagraph
500\let\stoppar \stopparagraph
501
502\def\strc_tags_document_start_indeed
503  {\glet\strc_tags_document_start_indeed\relax
504   \dostarttagged\t!document\empty}
505
506\def\strc_tags_document_stop_indeed
507  {\glet\strc_tags_document_stop_indeed\relax
508   \dostoptagged}
509
510\appendtoks
511    \strc_tags_document_start_indeed % here because otherwise products don't get a root (starttext before env)
512\to \everyenableelements
513
514% \appendtoks
515%     \strc_tags_document_start_indeed
516% \to \everystarttext
517
518\appendtoks
519    \strc_tags_document_stop_indeed
520\to \everystoptext
521
522\appendtoks
523    \strc_tags_disable_elements
524    \strc_tags_disable
525\to \everybeforepagebody
526
527%D This will only work well with sane use.
528
529% \appendtoks
530%     {%
531%         \doglobal\appendtoks
532%             \strc_tags_start_yes_ignore
533%         \to \everybeforepagebody
534%         \doglobal\appendtoks
535%             \strc_tags_stop_yes_ignore
536%         \to \everyafterpagebody
537%     }%
538% \to \everyenableelements
539
540% This doesn't work well either, so instead we handle the ornaments in the
541% tagging in a different way (see attr -> false code).
542
543% \appendtoks
544%     \dostartignoretagging
545% \to \everybeforepagebody
546%
547% \appendtoks
548%     \dostopignoretagging
549% \to \everyafterpagebody
550
551% \doifelseinelement{structure:section}            {yes} {no}
552% \doifelseinelement{structure:chapter}            {yes} {no}
553% \doifelseinelement{division:*-structure:chapter} {yes} {no}
554
555\unexpanded\def\doifelseinelement#1%
556  {\clf_doifelseinelement{#1}}
557
558\let\doifinelementelse\doifelseinelement
559
560\unexpanded\def\taggedlabeltexts#1#2#3% experimental: label, numberdetail, numbercontent
561  {\begingroup
562   \dostarttagged\t!label{#1}%
563   \labeltexts{#1}%
564     {\dostoptagged
565      \dostarttagged\t!number{#2}%
566      #3%
567      \dostoptagged
568      \dostarttagged\t!label{#1}}%
569   \dostoptagged
570   \endgroup}
571
572\unexpanded\def\namedtaggedlabeltexts#1#2#3#4#5% experimental: labeltag label numbertag numberdetail numbercontent
573  {\begingroup
574   \dostarttagged{#1}{#2}%
575   \labeltexts{#2}%
576     {\dostoptagged
577      \dostarttagged{#3}{#4}%
578      #5%
579      \dostoptagged
580      \dostarttagged{#1}{#2}}%
581   \dostoptagged
582   \endgroup}
583
584%D Metadata is added after the following structure element so
585%D here we get some as child of the document root and some as child
586%D of the chapter element.
587%D
588%D \settaggedmetadata[title=Hello World!,author=Hans Hagen]
589%D
590%D \starttyping
591%D \starttext
592%D   \startelement[ignore]
593%D     \input tufte
594%D   \stopelement
595%D   \par \input ward \par
596%D   \settaggedmetadata[whatever=Again and Again]
597%D   \startchapter[title=test]
598%D     \input ward
599%D   \stopchapter
600%D \stoptext
601%D \stoptyping
602
603\unexpanded\def\settaggedmetadata[#1]%
604  {\clf_settaggedmetadata{#1}}
605
606%D An overload:
607
608\let\strc_tagged_saved_bpar\bpar
609\let\strc_tagged_saved_epar\epar
610
611\unexpanded\def\bpar{\dostarttagged\t!paragraph\empty\strc_tagged_saved_bpar}
612\unexpanded\def\epar{\strc_tagged_saved_epar\dostoptagged}
613
614% \def\untagged{attr \taggedattribute\attributeunsetvalue}
615
616\protect
617