xml-mkiv-examples.tex /size: 21 Kb    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/xml
2
3\environment xml-mkiv-style
4
5\startcomponent xml-mkiv-examples
6
7\startchapter[title=Examples]
8
9\startsection[title=attribute chains]
10
11In \CSS, when an attribute is not present, the parent element is checked, and when
12not found again, the lookup follows the chain till a match is found or the root is
13reached. The following example demonstrates how such a chain lookup works.
14
15\startbuffer[test]
16<something mine="1" test="one" more="alpha">
17  <whatever mine="2" test="two">
18    <whocares mine="3">
19      <!-- this is a test -->
20    </whocares>
21  </whatever>
22</something>
23\stopbuffer
24
25\typebuffer[test]
26
27We apply the following setups to this tree:
28
29\startbuffer[setups]
30\startxmlsetups xml:common
31    [
32        \xmlchainatt{#1}{mine},
33        \xmlchainatt{#1}{test},
34        \xmlchainatt{#1}{more},
35        \xmlchainatt{#1}{none}
36    ]\par
37\stopxmlsetups
38
39\startxmlsetups xml:something
40    something: \xmlsetup{#1}{xml:common}
41    \xmlflush{#1}
42\stopxmlsetups
43
44\startxmlsetups xml:whatever
45    whatever: \xmlsetup{#1}{xml:common}
46    \xmlflush{#1}
47\stopxmlsetups
48
49\startxmlsetups xml:whocares
50    whocares: \xmlsetup{#1}{xml:common}
51    \xmlflush{#1}
52\stopxmlsetups
53
54\startxmlsetups xml:mysetups
55    \xmlsetsetup{#1}{something|whatever|whocares}{xml:*}
56\stopxmlsetups
57
58\xmlregisterdocumentsetup{example-1}{xml:mysetups}
59
60\xmlprocessbuffer{example-1}{test}{}
61\stopbuffer
62
63\typebuffer[setups]
64
65This gives:
66
67\start
68    \getbuffer[setups]
69\stop
70
71\stopsection
72
73\startsection[title=conditional setups]
74
75Say that we have this code:
76
77\starttyping
78\xmldoifelse {#1} {/what[@a='1']} {
79    \xmlfilter {#1} {/what/command('xml:yes')}
80} {
81    \xmlfilter {#1} {/what/command('xml:nop')}
82}
83\stoptyping
84
85Here we first determine if there is a child \type {what} with attribute \type {a}
86set to \type {1}. Depending on the outcome again we check the child nodes for
87being named \type {what}. A faster solution which also takes less code is this:
88
89\starttyping
90\xmlfilter {#1} {/what[@a='1']/command('xml:yes','xml:nop')}
91\stoptyping
92
93\stopsection
94
95\startsection[title=manipulating]
96
97Assume that we have the following \XML\ data:
98
99\startbuffer[test]
100<A>
101  <B>right</B>
102  <B>wrong</B>
103</A>
104\stopbuffer
105
106\typebuffer[test]
107
108But, instead of \type {right} we want to see \type {okay}. We can do that with a
109finalizer:
110
111\startbuffer
112\startluacode
113local rehash = {
114    ["right"] = "okay",
115}
116
117function xml.finalizers.tex.Okayed(collected,what)
118    for i=1,#collected do
119        if what == "all" then
120            local str = xml.text(collected[i])
121            context(rehash[str] or str)
122        else
123            context(str)
124        end
125    end
126end
127\stopluacode
128\stopbuffer
129
130\typebuffer \getbuffer
131
132\startbuffer
133\startxmlsetups xml:A
134	\xmlflush{#1}
135\stopxmlsetups
136
137\startxmlsetups xml:B
138    (It's \xmlfilter{#1}{./Okayed("all")})
139\stopxmlsetups
140
141\startxmlsetups xml:testsetups
142	\xmlsetsetup{#1}{A|B}{xml:*}
143\stopxmlsetups
144
145\xmlregisterdocumentsetup{example-2}{xml:testsetups}
146\xmlprocessbuffer{example-2}{test}{}
147\stopbuffer
148
149\typebuffer
150
151The result is: \start \inlinebuffer \stop
152
153\stopsection
154
155\startsection[title=cross referencing]
156
157A rather common way to add cross references to \XML\ files is to borrow the
158asymmetrical id's from \HTML. This means that one cannot simply use a value
159of (say) \type {href} to locate an \type {id}. The next example came up on
160the \CONTEXT\ mailing list.
161
162\startbuffer[test]
163<doc>
164    <p>Text
165        <a href="#fn1" class="footnoteref" id="fnref1"><sup>1</sup></a> and
166        <a href="#fn2" class="footnoteref" id="fnref2"><sup>2</sup></a>
167    </p>
168    <div class="footnotes">
169        <hr />
170        <ol>
171            <li id="fn1"><p>A footnote.<a href="#fnref1"></a></p></li>
172            <li id="fn2"><p>A second footnote.<a href="#fnref2"></a></p></li>
173        </ol>
174    </div>
175</doc>
176\stopbuffer
177
178\typebuffer[test]
179
180We give two variants for dealing with such references. The first solution does
181lookups and depending on the size of the file can be somewhat inefficient.
182
183\startbuffer
184\startxmlsetups xml:doc
185    \blank
186    \xmlflush{#1}
187    \blank
188\stopxmlsetups
189
190\startxmlsetups xml:p
191    \xmlflush{#1}
192\stopxmlsetups
193
194\startxmlsetups xml:footnote
195    (variant 1)\footnote
196        {\xmlfirst
197            {example-3-1}
198            {div[@class='footnotes']/ol/li[@id='\xmlrefatt{#1}{href}']}}
199\stopxmlsetups
200
201\startxmlsetups xml:initialize
202    \xmlsetsetup{#1}{p|doc}{xml:*}
203    \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
204    \xmlsetsetup{#1}{div[@class='footnotes']}{xml:nothing}
205\stopxmlsetups
206
207\xmlresetdocumentsetups{*}
208\xmlregisterdocumentsetup{example-3-1}{xml:initialize}
209
210\xmlprocessbuffer{example-3-1}{test}{}
211\stopbuffer
212
213\typebuffer
214
215This will typeset two footnotes.
216
217\getbuffer
218
219The second variant collects the references so that the time spend on lookups is
220less.
221
222\startbuffer
223\startxmlsetups xml:doc
224    \blank
225    \xmlflush{#1}
226    \blank
227\stopxmlsetups
228
229\startxmlsetups xml:p
230    \xmlflush{#1}
231\stopxmlsetups
232
233\startluacode
234    userdata.notes =  {}
235\stopluacode
236
237\startxmlsetups xml:collectnotes
238    \ctxlua{userdata.notes['\xmlrefatt{#1}{id}'] = '#1'}
239\stopxmlsetups
240
241\startxmlsetups xml:footnote
242    (variant 2)\footnote
243        {\xmlflush
244            {\cldcontext{userdata.notes['\xmlrefatt{#1}{href}']}}}
245\stopxmlsetups
246
247\startxmlsetups xml:initialize
248    \xmlsetsetup{#1}{p|doc}{xml:*}
249    \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
250    \xmlfilter{#1}{div[@class='footnotes']/ol/li/command(xml:collectnotes)}
251    \xmlsetsetup{#1}{div[@class='footnotes']}{}
252\stopxmlsetups
253
254\xmlregisterdocumentsetup{example-3-2}{xml:initialize}
255
256\xmlprocessbuffer{example-3-2}{test}{}
257\stopbuffer
258
259\typebuffer
260
261This will again typeset two footnotes:
262
263\getbuffer
264
265\stopsection
266
267\startsection[title=mapping values]
268
269One way to process options \type {frame} in the example below is to map the
270values to values known by \CONTEXT.
271
272\startbuffer[test]
273<a>
274  <nattable frame="on">
275    <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
276    <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
277  </nattable>
278  <nattable frame="off">
279    <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
280    <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
281  </nattable>
282  <nattable frame="no">
283    <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
284    <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
285  </nattable>
286</a>
287\stopbuffer
288
289\typebuffer[test]
290
291\startbuffer
292\startxmlsetups xml:a
293    \xmlflush{#1}
294\stopxmlsetups
295
296\xmlmapvalue {nattable:frame} {on}  {on}
297\xmlmapvalue {nattable:frame} {yes} {on}
298\xmlmapvalue {nattable:frame} {off} {off}
299\xmlmapvalue {nattable:frame} {no}  {off}
300
301\startxmlsetups xml:nattable
302    \startplacetable[title=#1]
303        \setupTABLE[frame=\xmlval{nattable:frame}{\xmlatt{#1}{frame}}{on}]%
304        \bTABLE
305            \xmlflush{#1}
306        \eTABLE
307    \stopplacetable
308\stopxmlsetups
309
310\startxmlsetups xml:tr
311    \bTR
312        \xmlflush{#1}
313    \eTR
314\stopxmlsetups
315
316\startxmlsetups xml:td
317    \bTD
318        \xmlflush{#1}
319    \eTD
320\stopxmlsetups
321
322\startxmlsetups xml:testsetups
323    \xmlsetsetup{example-4}{a|nattable|tr|td|}{xml:*}
324\stopxmlsetups
325
326\xmlregisterdocumentsetup{example-4}{xml:testsetups}
327
328\xmlprocessbuffer{example-4}{test}{}
329\stopbuffer
330
331The \type {\xmlmapvalue} mechanism is rather efficient and involves a minimum
332of testing.
333
334\typebuffer
335
336We get:
337
338\getbuffer
339
340\stopsection
341
342\startsection[title=using \LUA]
343
344In this example we demonstrate how you can delegate rendering to \LUA. We
345will construct a so called extreme table. The input is:
346
347\startbuffer[demo]
348<?xml version="1.0" encoding="utf-8"?>
349
350<a>
351  <b> <c>1</c> <d>Text</d>           </b>
352  <b> <c>2</c> <d>More text</d>      </b>
353  <b> <c>2</c> <d>Even more text</d> </b>
354  <b> <c>2</c> <d>And more</d>       </b>
355  <b> <c>3</c> <d>And even more</d>  </b>
356  <b> <c>2</c> <d>The last text</d>  </b>
357</a>
358\stopbuffer
359
360\typebuffer[demo]
361
362The processor code is:
363
364\startbuffer[process]
365\startxmlsetups xml:test_setups
366    \xmlsetsetup{#1}{a|b|c|d}{xml:*}
367\stopxmlsetups
368
369\xmlregisterdocumentsetup{example-5}{xml:test_setups}
370
371\xmlprocessbuffer{example-5}{demo}{}
372\stopbuffer
373
374\typebuffer
375
376We color a sequence of the same titles (numbers here) differently. The first
377solution remembers the last title:
378
379\startbuffer
380\startxmlsetups xml:a
381    \startembeddedxtable
382        \xmlflush{#1}
383    \stopembeddedxtable
384\stopxmlsetups
385
386\startxmlsetups xml:b
387    \xmlfunction{#1}{test_ba}
388\stopxmlsetups
389
390\startluacode
391local lasttitle = nil
392
393function xml.functions.test_ba(t)
394    local title   = xml.text(t, "/c")
395    local content = xml.text(t, "/d")
396    context.startxrow()
397    context.startxcell {
398        background      = "color",
399        backgroundcolor = lasttitle == title and "colorone" or "colortwo",
400        foregroundstyle = "bold",
401        foregroundcolor = "white",
402    }
403    context(title)
404    lasttitle = title
405    context.stopxcell()
406    context.startxcell()
407    context(content)
408    context.stopxcell()
409    context.stopxrow()
410end
411\stopluacode
412\stopbuffer
413
414\typebuffer \getbuffer
415
416The \type {embeddedxtable} environment is needed because the table is picked up
417as argument.
418
419\startlinecorrection \getbuffer[process] \stoplinecorrection
420
421The second implemetation remembers what titles are already processed so here we
422can color the last one too.
423
424\startbuffer
425\startxmlsetups xml:a
426    \ctxlua{xml.functions.reset_bb()}
427    \startembeddedxtable
428        \xmlflush{#1}
429    \stopembeddedxtable
430\stopxmlsetups
431
432\startxmlsetups xml:b
433    \xmlfunction{#1}{test_bb}
434\stopxmlsetups
435
436\startluacode
437local titles
438
439function xml.functions.reset_bb(t)
440    titles = { }
441end
442
443function xml.functions.test_bb(t)
444    local title   = xml.text(t, "/c")
445    local content = xml.text(t, "/d")
446    context.startxrow()
447    context.startxcell {
448        background      = "color",
449        backgroundcolor = titles[title] and "colorone" or "colortwo",
450        foregroundstyle = "bold",
451        foregroundcolor = "white",
452    }
453    context(title)
454    titles[title] = true
455    context.stopxcell()
456    context.startxcell()
457    context(content)
458    context.stopxcell()
459    context.stopxrow()
460end
461\stopluacode
462\stopbuffer
463
464\typebuffer \getbuffer
465
466\startlinecorrection \getbuffer[process] \stoplinecorrection
467
468A solution without any state variable is given below.
469
470\startbuffer
471\startxmlsetups xml:a
472    \startembeddedxtable
473        \xmlflush{#1}
474    \stopembeddedxtable
475\stopxmlsetups
476
477\startxmlsetups xml:b
478    \xmlfunction{#1}{test_bc}
479\stopxmlsetups
480
481\startluacode
482function xml.functions.test_bc(t)
483    local title   = xml.text(t, "/c")
484    local content = xml.text(t, "/d")
485    context.startxrow()
486    local okay = xml.text(t,"./preceding-sibling::/[-1]") == title
487    context.startxcell {
488        background      = "color",
489        backgroundcolor = okay and "colorone" or "colortwo",
490        foregroundstyle = "bold",
491        foregroundcolor = "white",
492    }
493    context(title)
494    context.stopxcell()
495    context.startxcell()
496    context(content)
497    context.stopxcell()
498    context.stopxrow()
499end
500\stopluacode
501\stopbuffer
502
503\typebuffer \getbuffer
504
505\startlinecorrection \getbuffer[process] \stoplinecorrection
506
507Here is a solution that delegates even more to \LUA. The previous variants were
508actually not that safe with repect to special characters and didn't handle
509nested elements either but the next one does.
510
511\startbuffer[demo]
512<?xml version="1.0" encoding="utf-8"?>
513
514<a>
515  <b> <c>#1</c> <d>Text</d>                     </b>
516  <b> <c>#2</c> <d>More text</d>                </b>
517  <b> <c>#2</c> <d>Even more text</d>           </b>
518  <b> <c>#2</c> <d>And more</d>                 </b>
519  <b> <c>#3</c> <d>And even more</d>            </b>
520  <b> <c>#2</c> <d>Something <i>nested</i> </d> </b>
521</a>
522\stopbuffer
523
524\typebuffer[demo]
525
526We also need to map the \type {i} element.
527
528\startbuffer
529\startxmlsetups xml:a
530    \starttexcode
531        \xmlfunction{#1}{test_a}
532    \stoptexcode
533\stopxmlsetups
534
535\startxmlsetups xml:c
536    \xmlflush{#1}
537\stopxmlsetups
538
539\startxmlsetups xml:d
540    \xmlflush{#1}
541\stopxmlsetups
542
543\startxmlsetups xml:i
544    {\em\xmlflush{#1}}
545\stopxmlsetups
546
547\startluacode
548function xml.functions.test_a(t)
549    context.startxtable()
550    local previous = false
551    for b in xml.collected(lxml.getid(t),"/b") do
552        context.startxrow()
553            local current = xml.text(b,"/c")
554            context.startxcell {
555                background      = "color",
556                backgroundcolor = (previous == current) and "colorone" or "colortwo",
557                foregroundstyle = "bold",
558                foregroundcolor = "white",
559            }
560            lxml.first(b,"/c")
561            context.stopxcell()
562            context.startxcell()
563            lxml.first(b,"/d")
564            context.stopxcell()
565            previous = current
566        context.stopxrow()
567    end
568    context.stopxtable()
569end
570\stopluacode
571
572\startxmlsetups xml:test_setups
573    \xmlsetsetup{#1}{a|b|c|d|i}{xml:*}
574\stopxmlsetups
575
576\xmlregisterdocumentsetup{example-5}{xml:test_setups}
577
578\xmlprocessbuffer{example-5}{demo}{}
579\stopbuffer
580
581\typebuffer
582
583\startlinecorrection \getbuffer \stoplinecorrection
584
585The question is, do we really need \LUA ? Often we don't, apart maybe from an
586occasional special finalizer. A pure \TEX\ solution is given next:
587
588\startbuffer
589\startxmlsetups xml:a
590    \glet\MyPreviousTitle\empty
591    \glet\MyCurrentTitle \empty
592    \startembeddedxtable
593        \xmlflush{#1}
594    \stopembeddedxtable
595\stopxmlsetups
596
597\startxmlsetups xml:b
598    \startxrow
599        \xmlflush{#1}
600    \stopxrow
601\stopxmlsetups
602
603\startxmlsetups xml:c
604    \xdef\MyCurrentTitle{\xmltext{#1}{.}}
605    \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
606        \startxcell
607          [background=color,
608           backgroundcolor=colorone,
609           foregroundstyle=bold,
610           foregroundcolor=white]
611    } {
612        \glet\MyPreviousTitle\MyCurrentTitle
613        \startxcell
614          [background=color,
615           backgroundcolor=colortwo,
616           foregroundstyle=bold,
617           foregroundcolor=white]
618    }
619    \xmlflush{#1}
620    \stopxcell
621\stopxmlsetups
622
623\startxmlsetups xml:d
624    \startxcell
625        \xmlflush{#1}
626    \stopxcell
627\stopxmlsetups
628
629\startxmlsetups xml:i
630    {\em\xmlflush{#1}}
631\stopxmlsetups
632
633\startxmlsetups xml:test_setups
634    \xmlsetsetup{#1}{*}{xml:*}
635\stopxmlsetups
636
637\xmlregisterdocumentsetup{example-5}{xml:test_setups}
638
639\xmlprocessbuffer{example-5}{demo}{}
640\stopbuffer
641
642\typebuffer
643
644\startlinecorrection \getbuffer \stoplinecorrection
645
646You can even save a few lines of code:
647
648\starttyping
649\startxmlsetups xml:c
650    \xdef\MyCurrentTitle{\xmltext{#1}{.}}
651    \startxcell
652      [background=color,
653       backgroundcolor=color\ifx\MyPreviousTitle\MyCurrentTitle one\else two\fi,
654       foregroundstyle=bold,
655       foregroundcolor=white]
656    \xmlflush{#1}
657    \stopxcell
658    \glet\MyPreviousTitle\MyCurrentTitle
659\stopxmlsetups
660\stoptyping
661
662Or if you prefer:
663
664\starttyping
665\startxmlsetups xml:c
666    \xdef\MyCurrentTitle{\xmltext{#1}{.}}
667    \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
668        \xmlsetup{#1}{xml:c:one}
669    } {
670        \xmlsetup{#1}{xml:c:two}
671    }
672\stopxmlsetups
673
674\startxmlsetups xml:c:one
675    \startxcell
676      [background=color,
677       backgroundcolor=colorone,
678       foregroundstyle=bold,
679       foregroundcolor=white]
680    \xmlflush{#1}
681    \stopxcell
682\stopxmlsetups
683
684\startxmlsetups xml:c:two
685    \startxcell
686      [background=color,
687       backgroundcolor=colortwo,
688       foregroundstyle=bold,
689       foregroundcolor=white]
690    \xmlflush{#1}
691    \stopxcell
692    \global\let\MyPreviousTitle\MyCurrentTitle
693\stopxmlsetups
694\stoptyping
695
696These examples demonstrate that it doesn't hurt to know a little bit of \TEX\
697programming: defining macros and basic comparisons can come in handy. There are
698examples in the test suite, you can peek in the source code, you can consult
699the wiki or you can just ask on the list.
700
701\stopsection
702
703\startsection[title=last match]
704
705For the next example we use the following \XML\ input:
706
707\startbuffer[demo]
708<?xml version "1.0"?>
709<document>
710    <section id="1">
711        <content>
712            <p>first</p>
713            <p>second</p>
714        </content>
715    </section>
716    <section id="2">
717        <content>
718            <p>third</p>
719            <p>fourth</p>
720        </content>
721    </section>
722</document>
723\stopbuffer
724
725\typebuffer[demo]
726
727If you check if some element is present and then act accordingly, you can
728end up with doing the same lookup twice. Although it might sound inefficient,
729in practice it's often not measureable.
730
731\startbuffer
732\startxmlsetups xml:demo:document
733    \type{\xmlall{#1}{/section[@id='2']/content/p}}\par
734    \xmldoif{#1}{/section[@id='2']/content/p} {
735        \xmlall{#1}{/section[@id='2']/content/p}
736    }
737    \type{\xmllastmatch}\par
738    \xmldoif{#1}{/section[@id='2']/content/p} {
739        \xmllastmatch
740    }
741    \type{\xmlall{#1}{last-match::}}\par
742    \xmldoif{#1}{/section[@id='2']/content/p} {
743        \xmlall{#1}{last-match::}
744    }
745    \type{\xmlfilter{#1}{last-match::/command(xml:demo:p)}}\par
746    \xmldoif{#1}{/section[@id='2']/content/p} {
747        \xmlfilter{#1}{last-match::/command(xml:demo:p)}
748    }
749\stopxmlsetups
750
751\startxmlsetups xml:demo:p
752    \quad\xmlflush{#1}\endgraf
753\stopxmlsetups
754
755\startxmlsetups xml:demo:base
756    \xmlsetsetup{#1}{document|p}{xml:demo:*}
757\stopxmlsetups
758
759\xmlregisterdocumentsetup{example-6}{xml:demo:base}
760
761\xmlprocessbuffer{example-6}{demo}{}
762\stopbuffer
763
764\typebuffer
765
766In the second check we just flush the last match, so effective we do an \type
767{\xmlall} here. The third and fourth alternatives demonstrate how we can use
768\type {last-match} as axis. The gain is 10\% or more on the lookup but of course
769typesetting often takes relatively more time than the lookup.
770
771\startpacked
772\getbuffer
773\stoppacked
774
775\stopsection
776
777\startsection[title=Finalizers]
778
779The \XML\ parser is also available outside \TEX. Here is an example of its usage.
780We pipe the result to \TEX\ but you can do with \type {t} whatever you like.
781
782\startbuffer
783local x = xml.load("xml-mkiv-03.xml")
784local t = { }
785
786for c in xml.collected(x,"//*") do
787    if not c.special and not t[c.tg] then
788        t[c.tg] = true
789    end
790end
791
792context.tocontext(table.sortedkeys(t))
793\stopbuffer
794
795% \typebuffer
796
797This returns:
798
799\ctxluabuffer
800
801We can wrap this in a finalizer:
802
803\startbuffer
804xml.finalizers.taglist = function(collected)
805    local t = { }
806    for i=1,#collected do
807        local c = collected[i]
808        if not c.special then
809            local tg = c.tg
810            if tg and not t[tg] then
811                t[tg] = true
812            end
813        end
814    end
815    return table.sortedkeys(t)
816end
817\stopbuffer
818
819\typebuffer
820
821Or in a more extensive one:
822
823\startbuffer
824xml.finalizers.taglist = function(collected,parenttoo)
825    local t = { }
826    for i=1,#collected do
827        local c = collected[i]
828        if not c.special then
829            local tg = c.tg
830            if tg and not t[tg] then
831                t[tg] = true
832            end
833            if parenttoo then
834                local p = c.__p__
835                if p and not p.special then
836                    local tg = p.tg .. ":" .. tg
837                    if tg and not t[tg] then
838                        t[tg] = true
839                    end
840                end
841            end
842        end
843    end
844    return table.sortedkeys(t)
845end
846\stopbuffer
847
848\typebuffer \ctxluabuffer
849
850Usage is as follows:
851
852\startbuffer
853local x = xml.load("xml-mkiv-03.xml")
854local t = xml.applylpath(x,"//*/taglist()")
855
856context.tocontext(t)
857\stopbuffer
858
859\typebuffer
860
861And indeed we get:
862
863\ctxluabuffer
864
865But we can also say:
866
867\startbuffer
868local x = xml.load("xml-mkiv-03.xml")
869local t = xml.applylpath(x,"//*/taglist(true)")
870
871context.tocontext(t)
872\stopbuffer
873
874\typebuffer
875
876Now we get:
877
878\ctxluabuffer
879
880\stopsection
881
882\startsection[title=Pure xml]
883
884One might wonder how a \TEX\ macro package would look like when backslashes,
885dollars and percent signs would have no special meaning. In fact, it would be
886rather useless as interpreting commands are triggered by such characters. Any
887formatting or coding system needs such characters. Take \XML: angle brackets and
888ampersands are really special. So, no matter what system we use, we do have to
889deal with the (common) case where these characters need to be seen as they are.
890Normally escaping is the solution.
891
892The \CONTEXT\ interface for \XML\ suffers from this as well. You really don't
893want to know how many tricks are used for dealing with special characters and
894entities: there are several ways these travel through the system and it is
895possible to adapt and cheat. Especially roundtripped data (via tuc file) puts
896some demands on the system because when ts \XML\ can become \TEX\ and vise versa.
897The next example (derived from a mail on the list) demonstrates this:
898
899\starttyping
900\startbuffer[demo]
901<doc>
902    <pre><code>\ConTeXt\ is great</code></pre>
903
904    <pre><code>but you need to know some tricks</code></pre>
905</doc>
906\stopbuffer
907
908\startxmlsetups xml:initialize
909     \xmlsetsetup{#1}{doc|p|code}{xml:*}
910     \xmlsetsetup{#1}{pre/code}{xml:pre:code}
911\stopxmlsetups
912
913\xmlregistersetup{xml:initialize}
914
915\startxmlsetups xml:doc
916     \xmlflush{#1}
917\stopxmlsetups
918
919\startxmlsetups xml:pre:code
920    no solution
921    \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
922    \par
923    solution one \begingroup
924        \expandUx
925        \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
926    \endgroup
927    \par
928    solution two
929    \comment[symbol=Key, location=inmargin,color=yellow]{\xmlpure{#1}}
930    \par
931    \xmlprettyprint{#1}{tex}
932\stopxmlsetups
933
934\xmlprocessbuffer{main}{demo}{}
935\stoptyping
936
937The first comment (an interactive feature of \PDF\ comes out as:
938
939\starttyping
940\Ux {5C}ConTeXt\Ux {5C} is great
941\stoptyping
942
943The second and third comment are okay. It's one of the reasons why we have \type
944{\xmlpure}.
945
946\stopsection
947
948\stopchapter
949
950\stopcomponent
951