1
2
3\environment xmlmkivstyle
4
5\startcomponent xmlmkivexamples
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}{somethingwhateverwhocares}{xml:*}
56\stopxmlsetups
57
58\xmlregisterdocumentsetup{example1}{xml:mysetups}
59
60\xmlprocessbuffer{example1}{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} {whatcommand(xml:yes)}
80} {
81 \xmlfilter {#1} {whatcommand(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 (Its \xmlfilter{#1}{.Okayed("all")})
139\stopxmlsetups
140
141\startxmlsetups xml:testsetups
142 \xmlsetsetup{#1}{AB}{xml:*}
143\stopxmlsetups
144
145\xmlregisterdocumentsetup{example2}{xml:testsetups}
146\xmlprocessbuffer{example2}{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 ids 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 {example31}
198 {div[@class=footnotes]olli[@id=\xmlrefatt{#1}{href}]}}
199\stopxmlsetups
200
201\startxmlsetups xml:initialize
202 \xmlsetsetup{#1}{pdoc}{xml:*}
203 \xmlsetsetup{#1}{a[@class=footnoteref]}{xml:footnote}
204 \xmlsetsetup{#1}{div[@class=footnotes]}{xml:nothing}
205\stopxmlsetups
206
207\xmlresetdocumentsetups{*}
208\xmlregisterdocumentsetup{example31}{xml:initialize}
209
210\xmlprocessbuffer{example31}{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}{pdoc}{xml:*}
249 \xmlsetsetup{#1}{a[@class=footnoteref]}{xml:footnote}
250 \xmlfilter{#1}{div[@class=footnotes]ollicommand(xml:collectnotes)}
251 \xmlsetsetup{#1}{div[@class=footnotes]}{}
252\stopxmlsetups
253
254\xmlregisterdocumentsetup{example32}{xml:initialize}
255
256\xmlprocessbuffer{example32}{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{example4}{anattabletrtd}{xml:*}
324\stopxmlsetups
325
326\xmlregisterdocumentsetup{example4}{xml:testsetups}
327
328\xmlprocessbuffer{example4}{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="utf8"?>
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:testsetups
366 \xmlsetsetup{#1}{abcd}{xml:*}
367\stopxmlsetups
368
369\xmlregisterdocumentsetup{example5}{xml:testsetups}
370
371\xmlprocessbuffer{example5}{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}{testba}
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}{testbb}
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}{testbc}
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 didnt handle
509nested elements either but the next one does.
510
511\startbuffer[demo]
512<?xml version="1.0" encoding="utf8"?>
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}{testa}
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:testsetups
573 \xmlsetsetup{#1}{abcdi}{xml:*}
574\stopxmlsetups
575
576\xmlregisterdocumentsetup{example5}{xml:testsetups}
577
578\xmlprocessbuffer{example5}{demo}{}
579\stopbuffer
580
581\typebuffer
582
583\startlinecorrection \getbuffer \stoplinecorrection
584
585The question is, do we really need \LUA ? Often we dont, 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:testsetups
634 \xmlsetsetup{#1}{*}{xml:*}
635\stopxmlsetups
636
637\xmlregisterdocumentsetup{example5}{xml:testsetups}
638
639\xmlprocessbuffer{example5}{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 doesnt 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 its often not measureable.
730
731\startbuffer
732\startxmlsetups xml:demo:document
733 \type{\xmlall{#1}{section[@id=2]contentp}}\par
734 \xmldoif{#1}{section[@id=2]contentp} {
735 \xmlall{#1}{section[@id=2]contentp}
736 }
737 \type{\xmllastmatch}\par
738 \xmldoif{#1}{section[@id=2]contentp} {
739 \xmllastmatch
740 }
741 \type{\xmlall{#1}{lastmatch::}}\par
742 \xmldoif{#1}{section[@id=2]contentp} {
743 \xmlall{#1}{lastmatch::}
744 }
745 \type{\xmlfilter{#1}{lastmatch::command(xml:demo:p)}}\par
746 \xmldoif{#1}{section[@id=2]contentp} {
747 \xmlfilter{#1}{lastmatch::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}{documentp}{xml:demo:*}
757\stopxmlsetups
758
759\xmlregisterdocumentsetup{example6}{xml:demo:base}
760
761\xmlprocessbuffer{example6}{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 {lastmatch} 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("xmlmkiv03.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
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("xmlmkiv03.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("xmlmkiv03.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 dont
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}{docpcode}{xml:*}
910 \xmlsetsetup{#1}{precode}{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. Its one of the reasons why we have \type
944{\xmlpure}.
945
946\stopsection
947
948\stopchapter
949
950\stopcomponent
951 |