summaryrefslogtreecommitdiff
path: root/tex/context/modules
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/modules')
-rw-r--r--tex/context/modules/common/s-abr-01.tex370
-rw-r--r--tex/context/modules/common/s-abr-02.tex22
-rw-r--r--tex/context/modules/common/s-abr-03.tex22
-rw-r--r--tex/context/modules/common/s-abr-04.tex24
-rw-r--r--tex/context/modules/common/s-cdr-01.tex145
-rw-r--r--tex/context/modules/common/s-faq-00.tex93
-rw-r--r--tex/context/modules/common/s-faq-01.tex215
-rw-r--r--tex/context/modules/common/s-faq-02.tex63
-rw-r--r--tex/context/modules/common/s-faq-03.tex70
-rw-r--r--tex/context/modules/common/s-mag-01.tex438
-rw-r--r--tex/context/modules/common/s-mod.ctx24
-rw-r--r--tex/context/modules/common/s-pre-00.tex202
-rw-r--r--tex/context/modules/common/s-pre-01.tex404
-rw-r--r--tex/context/modules/common/s-pre-02.tex381
-rw-r--r--tex/context/modules/common/s-pre-03.tex257
-rw-r--r--tex/context/modules/common/s-pre-04.tex377
-rw-r--r--tex/context/modules/common/s-pre-05.tex240
-rw-r--r--tex/context/modules/common/s-pre-06.tex324
-rw-r--r--tex/context/modules/common/s-pre-07.tex212
-rw-r--r--tex/context/modules/common/s-pre-08.tex271
-rw-r--r--tex/context/modules/common/s-pre-09.tex380
-rw-r--r--tex/context/modules/common/s-pre-10.tex308
-rw-r--r--tex/context/modules/common/s-pre-11.tex220
-rw-r--r--tex/context/modules/common/s-pre-12.tex226
-rw-r--r--tex/context/modules/common/s-pre-13.tex302
-rw-r--r--tex/context/modules/common/s-pre-14.tex263
-rw-r--r--tex/context/modules/common/s-pre-15.tex186
-rw-r--r--tex/context/modules/common/s-pre-16.tex203
-rw-r--r--tex/context/modules/common/s-pre-18.tex173
-rw-r--r--tex/context/modules/common/s-pre-19.tex347
-rw-r--r--tex/context/modules/common/s-pre-22.tex319
-rw-r--r--tex/context/modules/common/s-pre-23.tex109
-rw-r--r--tex/context/modules/common/s-pre-26.tex255
-rw-r--r--tex/context/modules/common/s-pre-27.tex181
-rw-r--r--tex/context/modules/common/s-pre-50.tex101
-rw-r--r--tex/context/modules/common/s-pre-61.tex275
-rw-r--r--tex/context/modules/common/s-pre-62.tex224
-rw-r--r--tex/context/modules/common/s-pre-63.tex77
-rw-r--r--tex/context/modules/common/s-pre-64.tex208
-rw-r--r--tex/context/modules/common/s-pre-66.tex161
-rw-r--r--tex/context/modules/common/s-pre-67.tex155
-rw-r--r--tex/context/modules/common/s-pre-68.tex150
-rw-r--r--tex/context/modules/common/s-pre-93.tex208
-rw-r--r--tex/context/modules/common/s-pre-96.tex188
-rw-r--r--tex/context/modules/mkii/m-arabtex.mkii450
-rw-r--r--tex/context/modules/mkii/m-chart.mkii1315
-rw-r--r--tex/context/modules/mkii/m-chemic.mkii21
-rw-r--r--tex/context/modules/mkii/m-cweb.mkii1371
-rw-r--r--tex/context/modules/mkii/m-database.mkii420
-rw-r--r--tex/context/modules/mkii/m-dratex.mkii21
-rw-r--r--tex/context/modules/mkii/m-edtsnc.mkii207
-rw-r--r--tex/context/modules/mkii/m-educat.mkii217
-rw-r--r--tex/context/modules/mkii/m-format.mkii411
-rw-r--r--tex/context/modules/mkii/m-graph.mkii231
-rw-r--r--tex/context/modules/mkii/m-layout.mkii102
-rw-r--r--tex/context/modules/mkii/m-level.mkii94
-rw-r--r--tex/context/modules/mkii/m-narrowtt.mkii39
-rw-r--r--tex/context/modules/mkii/m-obsolete.mkii5
-rw-r--r--tex/context/modules/mkii/m-pdfsnc.mkii200
-rw-r--r--tex/context/modules/mkii/m-pictex.mkii239
-rw-r--r--tex/context/modules/mkii/m-pstricks.mkii127
-rw-r--r--tex/context/modules/mkii/m-r.mkii174
-rw-r--r--tex/context/modules/mkii/m-steps.mkii837
-rw-r--r--tex/context/modules/mkii/m-subsub.mkii76
-rw-r--r--tex/context/modules/mkii/m-tex4ht.mkii9
-rw-r--r--tex/context/modules/mkii/m-units.mkii904
-rw-r--r--tex/context/modules/mkii/m-visual.mkii315
-rw-r--r--tex/context/modules/mkii/ppchtex.mkii3555
-rw-r--r--tex/context/modules/mkii/rlxcache.rlx71
-rw-r--r--tex/context/modules/mkii/rlxtools.rlx136
-rw-r--r--tex/context/modules/mkii/s-chi-00.mkii76
-rw-r--r--tex/context/modules/mkii/s-fnt-01.mkii61
-rw-r--r--tex/context/modules/mkii/s-fnt-02.mkii133
-rw-r--r--tex/context/modules/mkii/s-grk-00.mkii77
-rw-r--r--tex/context/modules/mkii/s-jap-00.mkii23
-rw-r--r--tex/context/modules/mkii/s-map-10.mkii491
-rw-r--r--tex/context/modules/mkii/s-mod-00.mkii511
-rw-r--r--tex/context/modules/mkii/s-mod-01.mkii155
-rw-r--r--tex/context/modules/mkii/s-mod-02.mkii421
-rw-r--r--tex/context/modules/mkii/s-pre-17.mkii399
-rw-r--r--tex/context/modules/mkii/s-pre-30.mkii258
-rw-r--r--tex/context/modules/mkii/s-pre-60.mkii143
-rw-r--r--tex/context/modules/mkii/s-pre-71.mkii213
-rw-r--r--tex/context/modules/mkii/s-ptj-01.mkii425
-rw-r--r--tex/context/modules/mkii/s-syntax.mkii54
-rw-r--r--tex/context/modules/mkii/x-calcmath.mkii24
-rw-r--r--tex/context/modules/mkii/x-chemml.mkii212
-rw-r--r--tex/context/modules/mkii/x-chemml.xsd93
-rw-r--r--tex/context/modules/mkii/x-contml.mkii491
-rw-r--r--tex/context/modules/mkii/x-contml.xsd375
-rw-r--r--tex/context/modules/mkii/x-corres.mkii136
-rw-r--r--tex/context/modules/mkii/x-corres.rng170
-rw-r--r--tex/context/modules/mkii/x-dir-01.mkii145
-rw-r--r--tex/context/modules/mkii/x-dir-02.mkii130
-rw-r--r--tex/context/modules/mkii/x-dir-05.mkii51
-rw-r--r--tex/context/modules/mkii/x-fdf-00.mkii41
-rw-r--r--tex/context/modules/mkii/x-fe.mkii143
-rw-r--r--tex/context/modules/mkii/x-fig-00.dtd24
-rw-r--r--tex/context/modules/mkii/x-fig-00.mkii252
-rw-r--r--tex/context/modules/mkii/x-fig-00.xsd77
-rw-r--r--tex/context/modules/mkii/x-fig-01.mkii461
-rw-r--r--tex/context/modules/mkii/x-fig-02.mkii78
-rw-r--r--tex/context/modules/mkii/x-fig-03.mkii44
-rw-r--r--tex/context/modules/mkii/x-fo.mkii4057
-rw-r--r--tex/context/modules/mkii/x-foxet.mkii28
-rw-r--r--tex/context/modules/mkii/x-mathml.mkii28
-rw-r--r--tex/context/modules/mkii/x-mathml.xsd11
-rw-r--r--tex/context/modules/mkii/x-newcml.mkii456
-rw-r--r--tex/context/modules/mkii/x-newmme.mkii423
-rw-r--r--tex/context/modules/mkii/x-newmml.mkii2744
-rw-r--r--tex/context/modules/mkii/x-newmmo.mkii210
-rw-r--r--tex/context/modules/mkii/x-newpml.mkii250
-rw-r--r--tex/context/modules/mkii/x-om2cml.xsl1342
-rw-r--r--tex/context/modules/mkii/x-openmath.mkii4
-rw-r--r--tex/context/modules/mkii/x-openmath.xsl35
-rw-r--r--tex/context/modules/mkii/x-physml.mkii16
-rw-r--r--tex/context/modules/mkii/x-physml.xsd172
-rw-r--r--tex/context/modules/mkii/x-res-00.mkii67
-rw-r--r--tex/context/modules/mkii/x-res-01.mkii487
-rw-r--r--tex/context/modules/mkii/x-res-02.mkii72
-rw-r--r--tex/context/modules/mkii/x-res-03.mkii44
-rw-r--r--tex/context/modules/mkii/x-res-04.mkii336
-rw-r--r--tex/context/modules/mkii/x-res-08.mkii129
-rw-r--r--tex/context/modules/mkii/x-res-09.mkii69
-rw-r--r--tex/context/modules/mkii/x-res-10.mkii75
-rw-r--r--tex/context/modules/mkii/x-res-11.mkii110
-rw-r--r--tex/context/modules/mkii/x-res-12.mkii53
-rw-r--r--tex/context/modules/mkii/x-res-20.mkii231
-rw-r--r--tex/context/modules/mkii/x-res-50.mkii427
-rw-r--r--tex/context/modules/mkii/x-sch-00.mkii382
-rw-r--r--tex/context/modules/mkii/x-sch-01.mkii122
-rw-r--r--tex/context/modules/mkii/x-set-01.mkii79
-rw-r--r--tex/context/modules/mkii/x-set-02.mkii30
-rw-r--r--tex/context/modules/mkii/x-set-11.mkii837
-rw-r--r--tex/context/modules/mkii/x-set-12.mkii258
-rw-r--r--tex/context/modules/mkii/x-sm2om.xsl233
-rw-r--r--tex/context/modules/mkii/x-steps.mkii85
-rw-r--r--tex/context/modules/mkii/x-xml-01.mkii91
-rw-r--r--tex/context/modules/mkii/x-xml-02.mkii91
-rw-r--r--tex/context/modules/mkii/x-xml-11.mkii134
-rw-r--r--tex/context/modules/mkiv/m-barcodes.mkiv122
-rw-r--r--tex/context/modules/mkiv/m-chart.lua945
-rw-r--r--tex/context/modules/mkiv/m-chart.mkvi540
-rw-r--r--tex/context/modules/mkiv/m-chemic.mkiv20
-rw-r--r--tex/context/modules/mkiv/m-cweb.mkiv1373
-rw-r--r--tex/context/modules/mkiv/m-database.lua132
-rw-r--r--tex/context/modules/mkiv/m-database.mkiv211
-rw-r--r--tex/context/modules/mkiv/m-directives.mkiv3
-rw-r--r--tex/context/modules/mkiv/m-educat.mkiv217
-rw-r--r--tex/context/modules/mkiv/m-escrito.lua7088
-rw-r--r--tex/context/modules/mkiv/m-escrito.mkiv184
-rw-r--r--tex/context/modules/mkiv/m-fields.mkiv70
-rw-r--r--tex/context/modules/mkiv/m-format.mkiv411
-rw-r--r--tex/context/modules/mkiv/m-graph.mkiv133
-rw-r--r--tex/context/modules/mkiv/m-hemistich.mkiv120
-rw-r--r--tex/context/modules/mkiv/m-ipsum.mkiv198
-rw-r--r--tex/context/modules/mkiv/m-json.mkiv30
-rw-r--r--tex/context/modules/mkiv/m-layout.mkiv102
-rw-r--r--tex/context/modules/mkiv/m-logcategories.mkiv3
-rw-r--r--tex/context/modules/mkiv/m-markdown.lua824
-rw-r--r--tex/context/modules/mkiv/m-markdown.mkiv88
-rw-r--r--tex/context/modules/mkiv/m-mathcrap.mkiv76
-rw-r--r--tex/context/modules/mkiv/m-matrix.mkiv495
-rw-r--r--tex/context/modules/mkiv/m-mkii.mkiv21
-rw-r--r--tex/context/modules/mkiv/m-mkivhacks.mkiv50
-rw-r--r--tex/context/modules/mkiv/m-morse.mkvi273
-rw-r--r--tex/context/modules/mkiv/m-narrowtt.mkiv39
-rw-r--r--tex/context/modules/mkiv/m-nodechart.lua177
-rw-r--r--tex/context/modules/mkiv/m-nodechart.mkvi125
-rw-r--r--tex/context/modules/mkiv/m-ntb-to-xtb.mkiv5
-rw-r--r--tex/context/modules/mkiv/m-obsolete.mkiv5
-rw-r--r--tex/context/modules/mkiv/m-oldfun.mkiv714
-rw-r--r--tex/context/modules/mkiv/m-oldnum.mkiv416
-rw-r--r--tex/context/modules/mkiv/m-pictex.mkiv46
-rw-r--r--tex/context/modules/mkiv/m-pipemode.mkiv7
-rw-r--r--tex/context/modules/mkiv/m-pstricks.lua74
-rw-r--r--tex/context/modules/mkiv/m-pstricks.mkiv65
-rw-r--r--tex/context/modules/mkiv/m-punk.mkiv257
-rw-r--r--tex/context/modules/mkiv/m-scite.mkiv279
-rw-r--r--tex/context/modules/mkiv/m-spreadsheet.lua332
-rw-r--r--tex/context/modules/mkiv/m-spreadsheet.mkiv221
-rw-r--r--tex/context/modules/mkiv/m-sql.mkiv29
-rw-r--r--tex/context/modules/mkiv/m-steps.lua226
-rw-r--r--tex/context/modules/mkiv/m-steps.mkvi382
-rw-r--r--tex/context/modules/mkiv/m-subsub.mkiv76
-rw-r--r--tex/context/modules/mkiv/m-timing.mkiv102
-rw-r--r--tex/context/modules/mkiv/m-trackers.mkiv3
-rw-r--r--tex/context/modules/mkiv/m-translate.mkiv127
-rw-r--r--tex/context/modules/mkiv/m-units.mkiv912
-rw-r--r--tex/context/modules/mkiv/m-visual.mkiv809
-rw-r--r--tex/context/modules/mkiv/m-zint.mkiv112
-rw-r--r--tex/context/modules/mkiv/ppchtex.mkiv3445
-rw-r--r--tex/context/modules/mkiv/s-art-01.mkiv62
-rw-r--r--tex/context/modules/mkiv/s-def-01.mkiv10
-rw-r--r--tex/context/modules/mkiv/s-figures-names.mkiv99
-rw-r--r--tex/context/modules/mkiv/s-fnt-10.mkiv169
-rw-r--r--tex/context/modules/mkiv/s-fnt-20.mkiv161
-rw-r--r--tex/context/modules/mkiv/s-fnt-21.mkiv64
-rw-r--r--tex/context/modules/mkiv/s-fnt-24.mkiv83
-rw-r--r--tex/context/modules/mkiv/s-fonts-charts.mkiv204
-rw-r--r--tex/context/modules/mkiv/s-fonts-coverage.lua123
-rw-r--r--tex/context/modules/mkiv/s-fonts-coverage.mkiv131
-rw-r--r--tex/context/modules/mkiv/s-fonts-features.lua161
-rw-r--r--tex/context/modules/mkiv/s-fonts-features.mkiv82
-rw-r--r--tex/context/modules/mkiv/s-fonts-goodies.lua117
-rw-r--r--tex/context/modules/mkiv/s-fonts-goodies.mkiv37
-rw-r--r--tex/context/modules/mkiv/s-fonts-ligatures.mkiv209
-rw-r--r--tex/context/modules/mkiv/s-fonts-missing.lua91
-rw-r--r--tex/context/modules/mkiv/s-fonts-missing.mkiv56
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.lua326
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.mkiv115
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.lua68
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.mkiv39
-rw-r--r--tex/context/modules/mkiv/s-fonts-tables.lua363
-rw-r--r--tex/context/modules/mkiv/s-fonts-tables.mkiv38
-rw-r--r--tex/context/modules/mkiv/s-fonts-vectors.lua104
-rw-r--r--tex/context/modules/mkiv/s-fonts-vectors.mkiv72
-rw-r--r--tex/context/modules/mkiv/s-inf-01.mkvi260
-rw-r--r--tex/context/modules/mkiv/s-inf-02.mkiv27
-rw-r--r--tex/context/modules/mkiv/s-inf-03.mkiv372
-rw-r--r--tex/context/modules/mkiv/s-inf-04.mkiv48
-rw-r--r--tex/context/modules/mkiv/s-languages-counters.lua52
-rw-r--r--tex/context/modules/mkiv/s-languages-counters.mkiv30
-rw-r--r--tex/context/modules/mkiv/s-languages-frequencies.lua33
-rw-r--r--tex/context/modules/mkiv/s-languages-frequencies.mkiv38
-rw-r--r--tex/context/modules/mkiv/s-languages-hyphenation.lua135
-rw-r--r--tex/context/modules/mkiv/s-languages-hyphenation.mkiv77
-rw-r--r--tex/context/modules/mkiv/s-languages-sorting.lua118
-rw-r--r--tex/context/modules/mkiv/s-languages-sorting.mkiv30
-rw-r--r--tex/context/modules/mkiv/s-languages-system.lua62
-rw-r--r--tex/context/modules/mkiv/s-languages-system.mkiv32
-rw-r--r--tex/context/modules/mkiv/s-languages-words.lua32
-rw-r--r--tex/context/modules/mkiv/s-languages-words.mkiv22
-rw-r--r--tex/context/modules/mkiv/s-map-10.mkiv494
-rw-r--r--tex/context/modules/mkiv/s-math-characters.lua242
-rw-r--r--tex/context/modules/mkiv/s-math-characters.mkiv193
-rw-r--r--tex/context/modules/mkiv/s-math-coverage.lua197
-rw-r--r--tex/context/modules/mkiv/s-math-coverage.mkiv38
-rw-r--r--tex/context/modules/mkiv/s-math-extensibles.mkiv145
-rw-r--r--tex/context/modules/mkiv/s-math-parameters.lua135
-rw-r--r--tex/context/modules/mkiv/s-math-parameters.mkiv41
-rw-r--r--tex/context/modules/mkiv/s-math-repertoire.mkiv487
-rw-r--r--tex/context/modules/mkiv/s-mod-00.mkiv24
-rw-r--r--tex/context/modules/mkiv/s-mod-01.mkiv390
-rw-r--r--tex/context/modules/mkiv/s-mod-02.mkiv24
-rw-r--r--tex/context/modules/mkiv/s-pages-statistics.mkiv134
-rw-r--r--tex/context/modules/mkiv/s-physics-units.mkiv30
-rw-r--r--tex/context/modules/mkiv/s-pre-17.mkiv408
-rw-r--r--tex/context/modules/mkiv/s-pre-30.mkiv257
-rw-r--r--tex/context/modules/mkiv/s-pre-60.mkiv212
-rw-r--r--tex/context/modules/mkiv/s-pre-69.mkiv336
-rw-r--r--tex/context/modules/mkiv/s-pre-70.mkiv176
-rw-r--r--tex/context/modules/mkiv/s-pre-71.lua63
-rw-r--r--tex/context/modules/mkiv/s-pre-71.mkiv170
-rw-r--r--tex/context/modules/mkiv/s-present-tiles.mkiv318
-rw-r--r--tex/context/modules/mkiv/s-references-show.mkiv132
-rw-r--r--tex/context/modules/mkiv/s-reg-01.mkiv60
-rw-r--r--tex/context/modules/mkiv/s-set-31.mkiv118
-rw-r--r--tex/context/modules/mkiv/s-sql-tables.lua152
-rw-r--r--tex/context/modules/mkiv/s-sql-tables.mkiv30
-rw-r--r--tex/context/modules/mkiv/s-structure-sections.mkiv80
-rw-r--r--tex/context/modules/mkiv/s-syntax.mkiv96
-rw-r--r--tex/context/modules/mkiv/s-typesetting-kerning.mkiv209
-rw-r--r--tex/context/modules/mkiv/s-youless.mkiv171
-rw-r--r--tex/context/modules/mkiv/x-asciimath.lua2209
-rw-r--r--tex/context/modules/mkiv/x-asciimath.mkiv436
-rw-r--r--tex/context/modules/mkiv/x-calcmath.lua363
-rw-r--r--tex/context/modules/mkiv/x-calcmath.mkiv80
-rw-r--r--tex/context/modules/mkiv/x-cals.lua221
-rw-r--r--tex/context/modules/mkiv/x-cals.mkiv45
-rw-r--r--tex/context/modules/mkiv/x-chemml.lua51
-rw-r--r--tex/context/modules/mkiv/x-chemml.mkiv228
-rw-r--r--tex/context/modules/mkiv/x-ct.lua167
-rw-r--r--tex/context/modules/mkiv/x-ct.mkiv29
-rw-r--r--tex/context/modules/mkiv/x-entities.mkiv18
-rw-r--r--tex/context/modules/mkiv/x-foxet.mkiv29
-rw-r--r--tex/context/modules/mkiv/x-html.mkiv379
-rw-r--r--tex/context/modules/mkiv/x-ldx.ctx23
-rw-r--r--tex/context/modules/mkiv/x-ldx.lua341
-rw-r--r--tex/context/modules/mkiv/x-ldx.mkiv196
-rw-r--r--tex/context/modules/mkiv/x-math-svg.lua176
-rw-r--r--tex/context/modules/mkiv/x-mathml-basics.mkiv276
-rw-r--r--tex/context/modules/mkiv/x-mathml-html.mkiv40
-rw-r--r--tex/context/modules/mkiv/x-mathml.lua898
-rw-r--r--tex/context/modules/mkiv/x-mathml.mkiv2605
-rw-r--r--tex/context/modules/mkiv/x-newmml.mkiv16
-rw-r--r--tex/context/modules/mkiv/x-pfs-01.mkiv399
-rw-r--r--tex/context/modules/mkiv/x-pfsense.ctx15
-rw-r--r--tex/context/modules/mkiv/x-physml.mkiv16
-rw-r--r--tex/context/modules/mkiv/x-res-01.mkiv427
-rw-r--r--tex/context/modules/mkiv/x-res-50.mkiv431
-rw-r--r--tex/context/modules/mkiv/x-set-11.mkiv859
-rw-r--r--tex/context/modules/mkiv/x-set-12.mkiv267
-rw-r--r--tex/context/modules/mkiv/x-steps.mkiv102
-rw-r--r--tex/context/modules/mkiv/x-udhr.mkiv98
-rw-r--r--tex/context/modules/mkiv/x-xfdf.mkiv72
296 files changed, 85665 insertions, 0 deletions
diff --git a/tex/context/modules/common/s-abr-01.tex b/tex/context/modules/common/s-abr-01.tex
new file mode 100644
index 000000000..00a1a5c1e
--- /dev/null
+++ b/tex/context/modules/common/s-abr-01.tex
@@ -0,0 +1,370 @@
+%D \module
+%D [ file=s-abr-01,
+%D version=1996.01.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=General Abbreviations 1,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\setupsorting[logo][\c!style=\v!capital]
+
+\setupcapitals[\c!title=\v!no]
+
+\protect
+
+\logo [MKI] {MkI} % joke
+\logo [MKII] {MkII}
+\logo [MKIII] {MkIII} % joke
+\logo [MKIV] {MkIV}
+\logo [MKVI] {MkVI}
+\logo [MKIX] {MkIX}
+\logo [MKXI] {MkXI}
+\logo [MKIC] {MkIC}
+\logo [MKCI] {MkCI}
+\logo [MPII] {MpII}
+\logo [MPIV] {MpIV}
+
+%logo [FGA] {fga}
+%logo [FGBBS] {fgbbs}
+\logo [ACROBAT] {Acro\-bat}
+\logo [APA] {apa}
+\logo [AFM] {afm}
+\logo [API] {api}
+\logo [ALEPH] {Aleph} % {\mathematics{\aleph}}
+\logo [ALGOL] {ALGOL}
+\logo [AMS] {ams}
+\logo [AMSLATEX] {\AmSLaTeX}
+\logo [AMSTEX] {\AmSTeX}
+\logo [ANSI] {ansi}
+\logo [ARABTEX] {Arab\TeX}
+\logo [ASCII] {ascii}
+\logo [ASCIITEX] {ascii\TeX}
+\logo [ASCIIMATH] {AsciiMath}
+\logo [BACHOTEX] {Bacho\TeX}
+\logo [BIBTEX] {bib\TeX}
+\logo [MLBIBTEX] {MLbib\TeX}
+\logo [BLUESKY] {BlueSky}
+\logo [BMP] {bmp}
+\logo [BSD] {bsd}
+\logo [CCODE] {C}
+\logo [CPLUSPLUS] {C\high{++}}
+\logo [CALCMATH] {CalcMath}
+\logo [CLD] {cld}
+\logo [CD] {cd}
+\logo [CPU] {cpu}
+\logo [CDROM] {cdrom}
+\logo [CID] {cid}
+\logo [CJK] {cjk}
+\logo [CMR] {cmr}
+\logo [CLD] {cld}
+\logo [CMYK] {cmyk}
+\logo [CODHOST] {CodHost}
+\logo [CONTEXT] {\ConTeXt}
+\logo [CONTEXTWIKI] {\ConTeXt\ Wiki}
+\logo [CONTEXTGROUP] {\ConTeXt\ Group}
+\logo [CSS] {css}
+\logo [CTAN] {ctan}
+\logo [CTXTOOLS] {ctxtools}
+\logo [CWEB] {cweb}
+\logo [CSTUG] {cstug}
+\logo [DANTE] {Dante}
+\logo [DISTILLER] {distiller}
+\logo [DRATEX] {Dra\TeX}
+\logo [DSC] {dsc}
+\logo [DTD] {dtd}
+\logo [DTK] {dtk}
+\logo [DTP] {dtp}
+\logo [DVD] {dvd}
+\logo [DVI] {dvi}
+\logo [DVIPDFM] {dvipdfm}
+\logo [DVIPDFMX] {dvipdfmx}
+\logo [DVIPOS] {dvipos}
+\logo [DVIPS] {dvips}
+\logo [DVIPSONE] {dvipsone}
+\logo [DVISCR] {dviscr}
+\logo [DVIWINDO] {dviwindo}
+\logo [EBCDIC] {ebcdic}
+\logo [EC] {ec}
+\logo [EIFFEL] {Eiffel}
+\logo [EMACS] {emacs}
+\logo [EMTEX] {em\TeX}
+\logo [ENCODING] {enc}
+\logo [ENCTEX] {enc\TeX}
+\logo [EPUB] {ePub}
+\logo [EPS] {eps}
+\logo [ETEX] {\eTeX}
+\logo [EUROBACHOTEX] {EuroBacho\TeX}
+\logo [EUROMATH] {EuroMath}
+\logo [EUROTEX] {Euro\TeX}
+\logo [EXAMPLE] {eXaMpLe}
+\logo [EXAMPLED] {exampled}
+\logo [EXAMPLEQ] {exampleq}
+\logo [EXAMPLER] {exampler}
+\logo [EXAMPLET] {examplet}
+\logo [EXAMPLEX] {examplex}
+\logo [EXIMPLE] {eXiMpLe}
+\logo [FLAC] {flac}
+\logo [FAQ] {faq}
+\logo [FDF] {fdf}
+\logo [FONTFORGE] {FontForge}
+\logo [FOXET] {foXet}
+\logo [FPTEX] {fp\TeX}
+\logo [FREEBSD] {FreeBSD}
+\logo [FTP] {ftp}
+\logo [GHOSTSCRIPT] {Ghost\-script}
+\logo [GHOSTVIEW] {Ghost\-view}
+\logo [GIF] {gif}
+\logo [GNU] {gnu}
+\logo [GNUPLOT] {gnuplot}
+\logo [GS] {Ghost\-Script}
+\logo [GUST] {Gust}
+\logo [GCC] {gcc}
+\logo [GWTEX] {gw\TeX}
+\logo [HSB] {hsb}
+\logo [HTML] {html}
+\logo [HTTP] {http}
+\logo [HZ] {hz}
+\logo [IBM] {ibm}
+\logo [IMAGEMAGICK] {ImageMagick}
+\logo [INITEX] {ini\TeX}
+\logo [INRSTEX] {inrs\TeX}
+\logo [IO] {io}
+\logo [IRCNET] {IRCnet}
+\logo [ISO] {iso}
+\logo [JAVA] {Java}
+\logo [JAVASCRIPT] {Java\-Script}
+\logo [JPEG] {jpeg}
+\logo [JPG] {jpg}
+\logo [JBIG] {jbig}
+\logo [KPATHSEA] {kpathsea}
+\logo [KPSE] {kpse}
+\logo [KVM] {kvm}
+\logo [KPSEWHICH] {kpsewhich}
+\logo [MKTEXLSR] {mktexlsr}
+\logo [MYSQL] {MySQL}
+\logo [LAMSTEX] {\LamSTeX}
+\logo [LATEX] {\LaTeX}
+\logo [LATEXTE] {\LaTeX2e}
+\logo [LATEXTN] {\LaTeX2.09}
+\logo [LCD] {lcd}
+\logo [LINUX] {linux}
+\logo [LISP] {Lisp}
+\logo [LPEG] {lpeg}
+\logo [LUA] {Lua}
+\logo [LUAJIT] {LuaJIT}
+\logo [LUAJITTEX] {Luajit\TeX}
+\logo [LUATEX] {Lua\TeX}
+\logo [LUATOOLS] {luatools}
+\logo [LMX] {lmx}
+\logo [MACOSX] {MacOSX}
+\logo [MACROTEX] {Macro\TeX}
+\logo [MAKEMPY] {MakeMPY}
+\logo [MAPPING] {map}
+\logo [MAPS] {Maps}
+\logo [MATHML] {MathML}
+\logo [METAFONT] {\MetaFont}
+\logo [METAPOST] {\MetaPost}
+\logo [METATEX] {Meta\TeX}
+\logo [MIKTEX] {Mik\TeX}
+\logo [MINGW] {MingW}
+\logo [MLTEX] {ml\TeX}
+\logo [METATYPE] {MetaType1}
+\logo [MODULA] {Modula}
+\logo [MOV] {mov}
+\logo [MPS] {mps}
+\logo [MPTOPDF] {mptopdf}
+\logo [MPLIB] {mplib}
+\logo [MSDOS] {msdos}
+\logo [MICROSOFT] {Microsoft}
+\logo [MSWINDOWS] {MS~Windows}
+\logo [MSWORD] {MS~Word}
+\logo [MTXRUN] {mtxrun}
+\logo [MTXTOOLS] {mtxtools}
+\logo [NETPBM] {NetPBM}
+\logo [NTG] {ntg}
+\logo [NTS] {nts}
+\logo [OFM] {ofm}
+\logo [OMEGA] {Omega}
+\logo [OPENMATH] {OpenMath}
+\logo [OPENTYPE] {OpenType}
+\logo [OPI] {opi}
+\logo [OTEX] {Oriental \TeX}
+\logo [OTF] {otf}
+\logo [OTP] {otp}
+\logo [OVF] {ovf}
+\logo [PASCAL] {Pascal}
+\logo [PCTEX] {pc\TeX}
+\logo [PFA] {pfa}
+\logo [PFB] {pfb}
+\logo [PDF] {pdf}
+\logo [PDFETEX] {pdfe\TeX}
+\logo [PDFTEX] {pdf\TeX}
+\logo [PDFTOOLS] {pdftools}
+\logo [PDFTOPS] {pdftops}
+\logo [PERL] {Perl}
+\logo [PERLTK] {Perl/Tk}
+\logo [PICTEX] {\PiCTeX}
+\logo [PK] {pk}
+\logo [PLAIN] {Plain}
+\logo [PNG] {png}
+\logo [POSIX] {posix}
+\logo [POSTSCRIPT] {Post\-Script}
+\logo [PPCHTEX] {\PPCHTeX}
+\logo [PRAGMA] {Pragma ADE}
+\logo [PRESS] {press}
+\logo [PRIFIL] {prifil}
+\logo [PS] {Post\-Script}
+\logo [PSCHECK] {pscheck}
+\logo [PSTOEDIT] {pstoedit}
+\logo [PSTOPAGE] {pstopage}
+\logo [PSTOPDF] {pstopdf}
+\logo [PSTRICKS] {pstricks}
+\logo [RAM] {ram}
+\logo [READER] {Acro\-bat Reader}
+\logo [RELAXNG] {Relax\kern.125emNG}
+\logo [RGB] {rgb}
+\logo [RLXTOOLS] {rlxtools}
+\logo [RUBY] {Ruby}
+\logo [SCITE] {SciTE}
+\logo [SGML] {sgml}
+\logo [SI] {si}
+\logo [SQL] {sql}
+\logo [SSD] {ssd}
+\logo [SVG] {svg}
+\logo [STIX] {Stix}
+\logo [SUMATRAPDF] {SumatraPDF}
+\logo [SWIG] {swig}
+\logo [SWIGLIB] {SwigLib}
+\logo [TABLE] {\TaBlE}
+\logo [TCPIP] {tcp/ip}
+\logo [TDS] {tds} % no sc te
+\logo [TEI] {tei} % no sc te
+\logo [TETEX] {te\TeX} % no sc te
+\logo [TEX] {\TeX}
+\logo [TEXADRES] {\TeX adress}
+\logo [TEXBASE] {\TeX base}
+\logo [TEXEDIT] {\TeX edit}
+\logo [TEXEXEC] {\TeX exec}
+\logo [TEXFONT] {\TeX font}
+\logo [TEXFORM] {\TeX form}
+\logo [TEXLIVE] {\TeX Live}
+\logo [TEXLUA] {\TeX Lua}
+\logo [TEXMF] {texmf}
+\logo [TEXMFSTART] {texmfstart}
+\logo [TEXNL] {tex-nl}
+\logo [TEXSHOW] {\TeX show}
+\logo [TEXSPELL] {\TeX spell}
+\logo [TEXGYRE] {\TeX\ Gyre}
+\logo [TEXSYNC] {texsync}
+\logo [TEXTMATE] {TextMate}
+\logo [TEXTOOLS] {\TeX tools}
+\logo [TEXUTIL] {\TeX util}
+\logo [TEXWORK] {\TeX work}
+\logo [TEXWORKS] {\TeX works}
+\logo [TEXXET] {\TeX\XeT} \def\XeT{XeT}
+\logo [TFM] {tfm}
+\logo [TIF] {tif}
+\logo [TIFF] {tiff}
+\logo [TIFFINFO] {tiffinfo}
+\logo [TIFFTAGS] {tifftags}
+\logo [TMFTOOLS] {tmftools}
+\logo [TPIC] {tpic}
+\logo [TPM] {tpm}
+\logo [TRUETYPE] {TrueType}
+\logo [TTC] {ttc}
+\logo [TTF] {ttf}
+\logo [TUG] {tug}
+\logo [TUGBOAT] {Tug\-Boat}
+\logo [TUGNEWS] {Tug\-News}
+\logo [TYPEONE] {Type1}
+\logo [UCS] {ucs}
+\logo [UNICODE] {Uni\-code}
+\logo [UNIX] {Unix}
+\logo [URI] {uri}
+\logo [URL] {url}
+\logo [USA] {usa}
+\logo [USENET] {usenet}
+\logo [UTF] {utf}
+\logo [USB] {usb}
+\logo [VF] {vf}
+\logo [WDT] {wdt}
+\logo [WEB] {web}
+\logo [WEBC] {web2c}
+\logo [WIKI] {Wiki}
+\logo [WINDOWS] {Windows}
+\logo [WINNT] {WinNT}
+\logo [WINNX] {Win9x}
+\logo [WWW] {www}
+\logo [WTHREEC] {W3C}
+\logo [WYSIWYG] {wysiwyg}
+\logo [XDVI] {Xdvi}
+\logo [XETEX] {\XeTeX}
+\logo [XFDF] {xfdf}
+\logo [XHTML] {xhtml}
+\logo [XINDY] {Xindy}
+\logo [XITS] {Xits}
+\logo [XML] {xml}
+\logo [XPATH] {xpath}
+\logo [XMLTOOLS] {xmltools}
+\logo [XPDFETEX] {xpdfe\TeX}
+\logo [XSL] {xsl}
+\logo [XSLFO] {xsl-fo}
+\logo [XSLT] {xslt}
+\logo [XSLTPROC] {xsltproc}
+\logo [XYPIC] {XYPIC} % wrong logo
+\logo [VMWARE] {VMWare}
+\logo [YandY] {y\&y}
+\logo [ZIP] {zip}
+
+\def\METAFUN {\MetaFun}
+
+\logo [METAFUN] {\MetaFun}
+
+\def\SystemSpecialA#1{$\langle\it#1\rangle$}
+\def\SystemSpecialB#1{{\tttf<#1>}}
+
+\unexpanded\def\CATCODE {\SystemSpecialA{catcode}}
+\unexpanded\def\CATCODES {\SystemSpecialA{catcodes}}
+\unexpanded\def\DIMENSION {\SystemSpecialA{dimension}}
+\unexpanded\def\DIMENSIONS {\SystemSpecialA{dimensions}}
+\unexpanded\def\COUNTER {\SystemSpecialA{counter}}
+\unexpanded\def\COUNTERS {\SystemSpecialA{counters}}
+\unexpanded\def\HBOX {\SystemSpecialA{hbox}}
+\unexpanded\def\HBOXES {\SystemSpecialA{hboxes}}
+\unexpanded\def\VBOX {\SystemSpecialA{vbox}}
+\unexpanded\def\VBOXES {\SystemSpecialA{vboxes}}
+\unexpanded\def\BOX {\SystemSpecialA{box}}
+\unexpanded\def\BOXES {\SystemSpecialA{boxes}}
+\unexpanded\def\TOKENLIST {\SystemSpecialA{token list}}
+\unexpanded\def\TOKENLISTS {\SystemSpecialA{token lists}}
+\unexpanded\def\NEWLINE {\SystemSpecialA{newline}}
+\unexpanded\def\SKIP {\SystemSpecialA{skip}}
+\unexpanded\def\SKIPS {\SystemSpecialA{skips}}
+\unexpanded\def\MUSKIP {\SystemSpecialA{muskip}}
+\unexpanded\def\MUSKIPS {\SystemSpecialA{muskips}}
+\unexpanded\def\MARK {\SystemSpecialA{mark}}
+\unexpanded\def\MARKS {\SystemSpecialA{marks}}
+
+\unexpanded\def\SPACE {\SystemSpecialB{space}}
+\unexpanded\def\EOF {\SystemSpecialB{eof}}
+\unexpanded\def\TAB {\SystemSpecialB{tab}}
+\unexpanded\def\NEWPAGE {\SystemSpecialB{newpage}}
+\unexpanded\def\NEWLINE {\SystemSpecialB{newline}}
+
+\unexpanded\def\LUWATEEKH {لُواتيخ} % kh ī t ā w [u] l
+\unexpanded\def\luwateekh {luwātīkh}
+
+\doifmodeelse {mkiv} {
+ \unexpanded\def\THANH{H\agrave n Th\ecircumflexacute\ Th\agrave nh}
+} {
+ \unexpanded\def\THANH{H\`an Th\^e\llap{\raise 0.5ex\hbox{\'{}}} Th\`anh}
+}
+
+\endinput
diff --git a/tex/context/modules/common/s-abr-02.tex b/tex/context/modules/common/s-abr-02.tex
new file mode 100644
index 000000000..8bb6a2898
--- /dev/null
+++ b/tex/context/modules/common/s-abr-02.tex
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=s-abr-02,
+%D version=1996.01.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=General Abbreviations 2,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[abr-01]
+
+\unprotect
+
+\setupsorting[logo][\c!style=\v!smallcaps]
+
+\setupcapitals[\c!title=\v!no]
+
+\protect \endinput
diff --git a/tex/context/modules/common/s-abr-03.tex b/tex/context/modules/common/s-abr-03.tex
new file mode 100644
index 000000000..8247b68a9
--- /dev/null
+++ b/tex/context/modules/common/s-abr-03.tex
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=s-abr-03,
+%D version=1998.08.10,
+%D title=\CONTEXT\ Style File,
+%D subtitle=General Abbreviations 3,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[abr-01]
+
+\unprotect
+
+\setupsorting[logo][\c!style=\v!WORD]
+
+\protect
+
+\endinput
diff --git a/tex/context/modules/common/s-abr-04.tex b/tex/context/modules/common/s-abr-04.tex
new file mode 100644
index 000000000..23940b526
--- /dev/null
+++ b/tex/context/modules/common/s-abr-04.tex
@@ -0,0 +1,24 @@
+%D \module
+%D [ file=s-abr-04,
+%D version=1996.01.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=General Abbreviations 2,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[abr-01]
+
+\unprotect
+
+% \definealternativestyle [\v!mixed] [\font_style_pseudoMixedCapped] [\font_style_pseudoMixedCapped]
+
+\setupsorting[logo][\c!style=\font_style_pseudoMixedCapped]
+
+% \setupcapitals[\c!title=\v!no]
+
+\protect \endinput
diff --git a/tex/context/modules/common/s-cdr-01.tex b/tex/context/modules/common/s-cdr-01.tex
new file mode 100644
index 000000000..b0bced9da
--- /dev/null
+++ b/tex/context/modules/common/s-cdr-01.tex
@@ -0,0 +1,145 @@
+%D \module
+%D [ file=s-cdr-01,
+%D version=2001.2.07, % maybe earlier
+%D title=\CONTEXT\ Style File,
+%D subtitle=CDROM Cover,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[cdr-01]
+
+\setupmodule[cdr-01][option=]
+
+\def\PDFMPformoffset{20cm}
+
+\definepapersize
+ [CDcover]
+ [width=12.5cm,
+ height=12.4cm]
+
+\definelayout
+ [CDcover]
+ [topspace=5mm,
+ backspace=5mm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setuparranging
+ [2SIDE]
+
+\setuppapersize
+ [CDcover]
+ [A4,landscape]
+
+\setuplayout
+ [CDcover]
+
+\setuplayout
+ [location=middle]
+
+\setupcolors
+ [state=start]
+
+\setupbackgrounds
+ [leftpage]
+ [background=leftcover]
+
+\setupbackgrounds
+ [rightpage]
+ [background=rightcover]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\defineoverlay[leftcover] [\useMPgraphic{leftcover}]
+\defineoverlay[rightcover][\useMPgraphic{rightcover}]
+
+\definecolor [cd-color] [s=0]
+\definemeasure[cd-linewidth][.4pt]
+
+\doif {\moduleparameter{cdr-01}{option}} {light} {
+ \definecolor [cd-color] [s=.85]
+ \definemeasure[cd-linewidth][.2pt]
+}
+
+\startuseMPgraphic{leftcover}
+ StartPage ;
+ pickup pencircle scaled \measure{cd-linewidth} ;
+ draw
+ bottomboundary Page &
+ rightboundary Page &
+ topboundary Page withcolor \MPcolor{cd-color} ;
+ draw
+ bottomboundary (Page enlarged 3mm) &
+ rightboundary (Page enlarged 3mm) &
+ topboundary (Page enlarged 3mm) dashed evenly withcolor \MPcolor{cd-color} ;
+ StopPage ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rightcover}
+ StartPage ;
+ pickup pencircle scaled \measure{cd-linewidth} ;
+ draw
+ topboundary Page &
+ leftboundary Page &
+ bottomboundary Page withcolor \MPcolor{cd-color} ;
+ draw
+ topboundary (Page enlarged 3mm) &
+ leftboundary (Page enlarged 3mm) &
+ bottomboundary (Page enlarged 3mm) dashed evenly withcolor \MPcolor{cd-color} ;
+ draw
+ bottomboundary Page --
+ lrcorner Page shifted (-5mm,-1cm) --
+ llcorner Page shifted ( 5mm,-1cm) -- cycle withcolor \MPcolor{cd-color} ;
+ draw
+ topboundary Page --
+ ulcorner Page shifted ( 5mm, 1cm) --
+ urcorner Page shifted (-5mm, 1cm) -- cycle withcolor \MPcolor{cd-color} ;
+ StopPage ;
+ setbounds currentpicture to Page ;
+\stopuseMPgraphic
+
+\setupmakeup
+ [standard]
+ [doublesided=no,page=]
+
+\setuplayout
+ [topspace=5mm,
+ backspace=5mm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\defineframedtext
+ [maintext]
+ [background={foreground,color},
+ backgroundcolor=a-bit-white,
+ frame=off,
+ before=,
+ after=,
+ align=right,
+ strut=no,
+ height=fit,
+ width=\textheight]
+
+\stopmodule
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+ \startstandardmakeup
+ page 1
+ \stopstandardmakeup
+
+ \startstandardmakeup
+ page 2
+ \stopstandardmakeup
+\stoptext
diff --git a/tex/context/modules/common/s-faq-00.tex b/tex/context/modules/common/s-faq-00.tex
new file mode 100644
index 000000000..84055491f
--- /dev/null
+++ b/tex/context/modules/common/s-faq-00.tex
@@ -0,0 +1,93 @@
+%D \module
+%D [ file=s-faq-00,
+%D version=1997.21.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=FAQ Common Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[abr-01]
+
+\defineblock[question]
+\defineblock[answer]
+
+\def\ScreenFAQ {fs-\TagOfFAQ-\LanguageOfFAQ}
+\def\PaperFAQ {fp-\TagOfFAQ-\LanguageOfFAQ}
+\def\FileNameOfFAQ {fa-\TagOfFAQ-\LanguageOfFAQ}
+
+\language
+ [\HyphenationOfFAQ]
+
+\setupwhitespace
+ [big]
+
+\setupbodyfont
+ [ams]
+
+\setuptolerance
+ [tolerant]
+
+\setupregister
+ [index]
+ [indicator=no]
+
+\setupframedtexts
+ [width=\hsize]
+
+\setupblock
+ [question]
+ [before=\startframedtext,
+ after=\stopframedtext]
+
+\setupblock
+ [answer]
+ [after=\EndAnswer]
+
+\def\EndAnswer {}
+
+\def\AuthorOfFAQ {}
+\def\IndexOfFAQ {}
+
+\def\FrequentlyAskedQuestion#1#2%
+ {\page
+ \doglobal\increment\CurrentNOfFAQ
+ \pagereference[faq:\CurrentNOfFAQ]
+ \gdef\IndexOfFAQ{#1}
+ \gdef\AuthorOfFAQ{#2}}
+
+\newcounter\CurrentNOfFAQ
+
+\setuplabeltext [nl] [FAQ=Vaak gestelde vragen]
+\setuplabeltext [du] [FAQ=Oft gestellte Fragen]
+\setuplabeltext [en] [FAQ=Frequently Asked Questions]
+
+\setuplabeltext [nl] [about=over]
+\setuplabeltext [du] [about=zu]
+\setuplabeltext [en] [about=about]
+
+\setuplabeltext [nl] [version=Versie]
+\setuplabeltext [du] [version=Version]
+\setuplabeltext [en] [version=Version]
+
+\setuplabeltext [nl] [goback=terug]
+\setuplabeltext [du] [goback=zur\"uck]
+\setuplabeltext [en] [goback=go back]
+
+\setuplabeltext [nl] [paper=papier]
+\setuplabeltext [du] [paper=Papier]
+\setuplabeltext [en] [paper=paper]
+
+\setuplabeltext [nl] [faqs=FAQ's]
+\setuplabeltext [du] [faqs=FAQs]
+\setuplabeltext [en] [faqs=FAQ's]
+
+\setuplabeltext [nl] [index=index]
+\setuplabeltext [du] [index=Index]
+\setuplabeltext [en] [index=index]
+
+\endinput
diff --git a/tex/context/modules/common/s-faq-01.tex b/tex/context/modules/common/s-faq-01.tex
new file mode 100644
index 000000000..f6ee3ce06
--- /dev/null
+++ b/tex/context/modules/common/s-faq-01.tex
@@ -0,0 +1,215 @@
+%D \module
+%D [ file=s-faq-01,
+%D version=1997.21.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=FAQ Interactive Version,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[faq-00]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=.5cm,
+ backspace=.5cm,
+ margin=0pt,
+ height=fit,
+ header=0pt,
+ width=fit,
+ footer=0pt,
+ bottomdistance=12pt,
+ bottom=18pt]
+
+\setupinteractionscreen
+ [width=fit,
+ height=fit,
+ option=max]
+
+\setupinteraction
+ [state=start,
+ page=yes,
+ color=darkred,
+ contrastcolor=black,
+ menu=on]
+
+\setupcolors
+ [state=start]
+
+\setupbackgrounds
+ [state=repeat]
+
+\setupbackgrounds
+ [page]
+ [offset=3pt]
+
+\setupbackgrounds
+ [text]
+ [text]
+ [background={screen,go-on}]
+
+\setupbackgrounds
+ [bottom]
+ [text]
+ [background=screen]
+
+\setupframedtexts
+ [background=MyFrame,
+ backgroundcolor=white,
+ framecolor=darkred,
+ frame=overlay]
+
+\defineoverlay[go-on][\overlaybutton{forward}]
+
+\useexternaldocument
+ [paperfaq]
+ [\PaperFAQ]
+ []
+
+\setupregister
+ [index]
+ [coupling=yes,
+ unknownreference=none,
+ interaction=text]
+
+\coupleregister
+ [index]
+
+\defineinteractionmenu [bottom 1] [bottom] [state=stop]
+\defineinteractionmenu [bottom 2] [bottom] [state=stop]
+
+\setupinteractionmenu
+ [bottom, bottom 1, bottom 2]
+ [background=MyFrame,
+ backgroundcolor=white,
+ color=black,
+ contrastcolor=black,
+ frame=overlay,
+ framecolor=darkred,
+ dummy=yes,
+ middle=\hskip1em,
+ height=\bottomheight,
+ distance=overlay]
+
+\setupinteractionmenu
+ [bottom 1]
+ [{\hfill},
+ {\labeltext{paper}[paperfaq::]},
+ {\labeltext{goback}[PreviousJump]},
+ {\labeltext{faqs}[faqs]},
+ {\labeltext{index}[index]},
+ {\gobackwardcharacter[previouspage]},
+ {\goforwardcharacter[nextpage]}]
+
+\setupinteractionmenu
+ [bottom 2]
+ [{\CurrentIndexOfFAQ},
+ {\hfill},
+ {\labeltext{paper}[paperfaq::faq:\CurrentNOfFAQ]},
+ {\labeltext{goback}[PreviousJump]},
+ {\labeltext{faqs}[faqs]},
+ {\labeltext{index}[index]},
+ {\gobackwardcharacter[previouspage]},
+ {\goforwardcharacter[nextpage]}]
+
+\def\CurrentIndexOfFAQ%
+ {\bgroup
+ \setupinteraction[color=]%
+ \menubox[bottom]%
+ {\hskip-.5em\def\index{\hskip.5em\coupledindex}\IndexOfFAQ}%
+ \egroup}
+
+\setupinteractionmenu
+ [bottom 1]
+ [state=start]
+
+\def\EndAnswer
+ {\vfill
+ \bgroup
+ \tfx\setstrut
+ \framed
+ [frame=overlay,
+ framecolor=darkred,
+ background=MyFrame,
+ backgroundcolor=white]
+ {\AuthorOfFAQ}
+ \egroup}
+
+\def\TitlePage
+ {\startstandardmakeup
+ \blank[3*big]
+ \midaligned{\bfd \labeltext{FAQ}}
+ \blank[3*big]
+ \midaligned{\bfd \labeltext{about} \NameOfFAQ}
+ \blank[3*big]
+ \midaligned{\bfb \labeltext{version}: \currentdate}
+ \blank[3*big]
+ \midaligned{\tta \ListOfFAQ}
+ \vfill
+ \midaligned{\tta pragma@wxs.nl}
+ \blank[3*big]
+ \stopstandardmakeup}
+
+\def\StartReadingFAQ
+ {\setupinteractionmenu[bottom 1][state=stop]
+ \setupinteractionmenu[bottom 2][state=start]
+ \page}
+
+\def\StopReadingFAQ
+ {\page
+ \setupinteractionmenu[bottom 2][state=stop]
+ \setupinteractionmenu[bottom 1][state=start]}
+
+\def\FileWithFAQs
+ {\StartReadingFAQ
+ \input \FileNameOfFAQ \relax
+ \StopReadingFAQ}
+
+\def\IndexPage
+ {\page
+ \def\CurrentIndexOfFAQ{}
+ \def\NameOfFAQ{}
+ \pagereference[index]
+ \placeregister[index]
+ \page}
+
+\def\BeginFAQ
+ {\doglobal\increment\CurrentNOfFAQ
+ \setbox0=\vbox\bgroup
+ \setupframedtexts[before=,after=,linecorrection=off]
+ \startframedtext}
+
+\def\EndFAQ
+ {\stopframedtext
+ \egroup
+ \button
+ [color=,contrastcolor=,frame=overlay,offset=overlay]
+ {\copy0}
+ [faq:\CurrentNOfFAQ]
+ \vskip6pt}
+
+\def\AllFAQs
+ {\page
+ \def\CurrentIndexOfFAQ{}
+ \def\NameOfFAQ{}
+ \newcounter\CurrentNOfFAQ
+ \setupblock[question][before=\BeginFAQ,after=\EndFAQ]
+ \pagereference[faqs]
+ \useblocks[question]}
+
+\startuniqueMPgraphic{Frame}
+ path p ; p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
+ pickup pencircle scaled 2pt ;
+ fill p withcolor \MPcolor{\overlaycolor} ;
+ draw p withcolor \MPcolor{\overlaylinecolor} ;
+\stopuniqueMPgraphic
+
+\defineoverlay[MyFrame][\uniqueMPgraphic{Frame}]
+
+\endinput
diff --git a/tex/context/modules/common/s-faq-02.tex b/tex/context/modules/common/s-faq-02.tex
new file mode 100644
index 000000000..92aa1eca2
--- /dev/null
+++ b/tex/context/modules/common/s-faq-02.tex
@@ -0,0 +1,63 @@
+%D \module
+%D [ file=s-faq-02,
+%D version=1997.21.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=FAQ Paper Version,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[faq-00]
+
+\setuplayout
+ [header=0pt]
+
+\setuppagenumbering
+ [location=]
+
+\setupfootertexts
+ [\labeltext{FAQ}: \NameOfFAQ\IndexOfFAQ][pagenumber]
+
+\def\EndAnswer%
+ {\blank[2*big]
+ \page[no]
+ (\AuthorOfFAQ)}
+
+\def\TitlePage%
+ {\startstandardmakeup
+ \midaligned{\bfd \labeltext{FAQ}}
+ \blank[3*big]
+ \midaligned{\bfd \labeltext{about} \NameOfFAQ}
+ \blank[3*big]
+ \midaligned{\bfb \labeltext{version}: \currentdate}
+ \blank[3*big]
+ \midaligned{\tta \ListOfFAQ}
+ \vfill
+ \midaligned{\tta pragma@wxs.nl}
+ \blank[3*big]
+ \stopstandardmakeup}
+
+\def\StartReadingFAQ
+ {\page}
+
+\def\StopReadingFAQ
+ {\page}
+
+\def\FileWithFAQs
+ {\StartReadingFAQ
+ \input \FileNameOfFAQ \relax
+ \StopReadingFAQ}
+
+\def\IndexPage
+ {\page
+ \setupfootertexts[\labeltext{index}][]
+ \placeregister[index]}
+
+\def\AllFAQs
+ {}
+
+\endinput
diff --git a/tex/context/modules/common/s-faq-03.tex b/tex/context/modules/common/s-faq-03.tex
new file mode 100644
index 000000000..b1e1ef2c2
--- /dev/null
+++ b/tex/context/modules/common/s-faq-03.tex
@@ -0,0 +1,70 @@
+%D \module
+%D [ file=s-faq-03,
+%D version=1997.21.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=FAQ General Framework,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\def\StartFAQ[#1]%
+ {\getrawparameters[FAQ][name=,label=,language=,hyphenation=,url=,#1]
+ \let\NameOfFAQ \FAQname
+ \let\TagOfFAQ \FAQlabel
+ \let\LanguageOfFAQ \FAQlanguage
+ \let\HyphenationOfFAQ \FAQhyphenation
+ \let\ListOfFAQ \FAQurl
+ \doifmodeelse{screen}
+ {\usemodule[faq-01]}
+ {\usemodule[faq-02]}
+ \starttext
+ \TitlePage
+ \StartReadingFAQ}
+
+\def\StopFAQ
+ {\StopReadingFAQ
+ \IndexPage
+ \AllFAQs
+ \stoptext}
+
+\def\ProcessFAQ[#1]%
+ {\StartFAQ[#1]
+ \input \FileNameOfFAQ \relax
+ \StopFAQ}
+
+% for old times sake:
+
+\def\PDFscreenFAQ \name #1 \tag #2 \language #3 \hyphenation #4 \list #5
+ {\def\NameOfFAQ {#1}
+ \def\TagOfFAQ {#2}
+ \def\LanguageOfFAQ {#3}
+ \def\HyphenationOfFAQ {#4}
+ \def\ListOfFAQ {#5}
+ \usemodule[faq-01]
+ \starttext
+ \TitlePage
+ \FileWithFAQs
+ \IndexPage
+ \AllFAQs
+ \stoptext}
+
+\def\PDFpaperFAQ \name #1 \tag #2 \language #3 \hyphenation #4 \list #5
+ {\def\NameOfFAQ {#1}
+ \def\TagOfFAQ {#2}
+ \def\LanguageOfFAQ {#3}
+ \def\HyphenationOfFAQ {#4}
+ \def\ListOfFAQ {#5}
+ \usemodule[faq-02]
+ \starttext
+ \TitlePage
+ \FileWithFAQs
+ \IndexPage
+ \stoptext}
+
+\let\DVIpaperFAQ\PDFscreenFAQ
+
+\endinput
diff --git a/tex/context/modules/common/s-mag-01.tex b/tex/context/modules/common/s-mag-01.tex
new file mode 100644
index 000000000..e2d30f4e5
--- /dev/null
+++ b/tex/context/modules/common/s-mag-01.tex
@@ -0,0 +1,438 @@
+%D \module
+%D [ file=s-mag-01,
+%D version=2002.12.14,
+%D title=\CONTEXT\ Style File,
+%D subtitle=\CONTEXT\ Magazine Base Style,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% This style is used for producing explanationary documents.
+% Don't misuse it for other purposes, since it may confuse
+% users. Don't change the title either, since it provides a
+% way to categorize documents. Numbers are disabled in
+% instances produced outside PRAGMA ADE.
+%
+% The layout setup is such that one has several text areas
+% available: headers and footers, margins and edges as well
+% as the main text area. The surrounding (gray) makes the
+% main page stand out and is suitable for viewing in spread
+% mode.
+%
+% Since this style is under constant construction, messing
+% around with settings will produce unwanted side effects.
+% So, if some feature or settings is needed, let me know.
+
+% todo: mp frames
+
+\setvariables[magazine][number=0]
+\setvariables[magazine][author=]
+\setvariables[magazine][title={Zero Issue}]
+\setvariables[magazine][date=\currentdate]
+
+% These are reserved for PRAGMA-ADE, don't use them yourself!
+
+% \setvariables[magazine][main=Tricky]
+% \setvariables[magazine][main=Update]
+% \setvariables[magazine][main=HOWTO]
+
+% \setvariables[magazine][main=This Way] % preludes to a/the manual
+% \setvariables[magazine][main=A Better Way] % dirty versus clean
+% \setvariables[magazine][main=No Way] % how users should not do it
+% \setvariables[magazine][main=Your Way] % how users do it
+% \setvariables[magazine][main=My Way] % how users do it
+% \setvariables[magazine][main=Our Way] % how we do things at pragma
+% \setvariables[magazine][main=Their Way] % how to do latex things in context
+
+\setvariables[magazine][main=My Way]
+
+\startmode[atpragma]
+ \setvariables[magazine][main=This Way]
+\stopmode
+
+\definepapersize
+ [magazine]
+ [width=\dimexpr\paperwidth-.1\paperwidth\relax,
+ height=\dimexpr\paperheight-.1\paperheight\relax]
+
+\setuppapersize
+ [magazine]
+ [A4]
+
+\setupinteractionscreen
+ [option=doublesided]
+
+\definecolor[OuterColor][s=.3]
+\definecolor[InnerColor][s=.8]
+\definecolor[MainColor] [s=.2]
+\definecolor[TitleColor][s=.7]
+
+\definecolor[MyRed] [r=.6]
+\definecolor[MyGreen][g=.6]
+\definecolor[MyBlue] [b=.6]
+
+\startuseMPgraphic{paper}
+ sh := define_circular_shade(a,a,0,bbheight(OverlayBox),
+ \MPcolor{InnerColor},\MPcolor{OuterColor}) ;
+ fill OverlayBox withshade sh ;
+\stopuseMPgraphic
+
+\startreusableMPgraphic{middlepaper}
+ pair a ; a := center OverlayBox ;
+ \includeMPgraphic{paper}
+\stopreusableMPgraphic
+
+\startreusableMPgraphic{rightpaper}
+ pair a ; a := .5[urcorner OverlayBox,lrcorner OverlayBox] ;
+ \includeMPgraphic{paper}
+\stopreusableMPgraphic
+
+\startreusableMPgraphic{leftpaper}
+ pair a ; a := .5[ulcorner OverlayBox,llcorner OverlayBox] ;
+ \includeMPgraphic{paper}
+\stopreusableMPgraphic
+
+\startreusableMPgraphic{page}
+ fill OverlayBox withcolor white ;
+\stopreusableMPgraphic
+
+\startusableMPgraphic{text}
+ StartPage ;
+ for i = Header,Text,Footer :
+ for j = LeftEdge, LeftMargin, Text, RightMargin, RightEdge :
+ draw Field[i][j] withpen pencircle scaled .5pt ;
+ endfor ;
+ endfor ;
+ StopPage ;
+ setbounds currentpicture to Field[Text][Text] ;
+\stopusableMPgraphic
+
+\startsetups[paper]
+
+ \doifmodeelse{*makeup}
+ {\reuseMPgraphic{middlepaper}}
+ {\doifoddpageelse
+ {\reuseMPgraphic{rightpaper}}
+ {\reuseMPgraphic{leftpaper}}}
+
+\stopsetups
+
+\defineoverlay[paper] [\setups{paper}]
+\defineoverlay[page] [\reuseMPgraphic{page}]
+\defineoverlay[text] [\doifmode{frame}{\useMPgraphic{text}}]
+
+\setupbackgrounds [paper] [background=paper]
+\setupbackgrounds [page] [background={page,title}]
+\setupbackgrounds [text] [background=text]
+
+\definelayer
+ [title]
+ [state=repeat,
+ hoffset=-1cm,
+ voffset=1cm,
+ width=\paperwidth,
+ height=\paperheight]
+
+\setupoutput
+ [pdftex]
+
+\setuplayout
+ [width=middle,
+ topspace=1.5cm,
+ height=middle,
+ header=1.5cm,
+ footer=1cm,
+ %grid=yes,
+ headerdistance=.25cm,
+ footerdistance=.5cm,
+ backspace=3cm,
+ margin=1.5cm,
+ margindistance=.25cm,
+ edge=.75cm,
+ edgedistance=.25cm,
+ bottomdistance=1.5cm,
+ bottom=.1\printpaperheight]
+
+\definelayout
+ [makeup]
+ [topspace=1cm,
+ backspace=1cm,
+ header=0pt,
+ footer=0pt,
+ bottom=0pt]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\setupcolors
+ [state=start]
+
+\usetypescript
+ [palatino][\defaultencoding]
+
+\setupbodyfont
+ [palatino,10pt]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+\appendtoks\setups[papershift]\to\beforeeverypage
+
+\startsetups[papershift]
+
+ \setuppapersize[top=\vskip.5cm,bottom=\vss]
+
+ \doifmodeelse{*makeup}
+ {\setuppapersize[left=\hfill,right=\hfill]}
+ {\doifoddpageelse
+ {\setuppapersize[right=\hfill]}
+ {\setuppapersize[left=\hfill]}}
+
+\stopsetups
+
+\setupbottomtexts
+ [\setups{rightbanner}] []
+ [] [\setups{leftbanner}]
+
+\startsetups [leftbanner]
+
+ \definedfont[Regular at \the\bottomheight]
+ \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}}
+ \ht\scratchbox1ex
+ \dp\scratchbox\zeropoint
+ \MainColor
+ \definedfont[Regular sa 2]
+ \doifsomething{\getvariable{magazine}{number}}
+ {\doifnot{\getvariable{magazine}{number}}{0}
+ {\#\getvariable{magazine}{number}}}
+ \quad
+ \currentdate
+ \quad
+ \scale[height=.25\bottomheight]{\box\scratchbox}
+ \quad
+ \hbox to 1.5em{\hss\pagenumber\hss}
+ \quad
+ \hskip-\backspace
+
+\stopsetups
+
+\startsetups [rightbanner]
+
+ \definedfont[Regular at \the\bottomheight]
+ \setbox\scratchbox\hbox{\TitleColor\getvariable{magazine}{main}}
+ \ht\scratchbox1ex
+ \dp\scratchbox\zeropoint
+ \MainColor
+ \hskip-\backspace
+ \definedfont[Regular sa 2]
+ \quad
+ \hbox to 1.5em{\hss\pagenumber\hss}
+ \quad
+ \scale[height=.25\bottomheight]{\box\scratchbox}
+ \quad
+ \currentdate
+ \quad
+ \doifmode{atpragma}{\#\getvariable{magazine}{number}}
+
+\stopsetups
+
+\startsetups[titlepage]
+
+ \disablemode[frame]
+
+ \setuplayout[makeup]
+
+ \startstandardmakeup[doublesided=no]
+
+ \dontcomplain
+
+ \definelayer
+ [makeup]
+ [width=\textwidth,
+ height=\textheight]
+
+ \setlayerframed
+ [makeup]
+ [corner={left,top},location={right,bottom}]
+ [frame=off,
+ foregroundcolor=MainColor]
+ {\scale
+ [width=\makeupwidth]
+ {\definedfont[Regular sa 10]%
+ \getvariable{magazine}{main}}}
+
+ \setlayerframed
+ [makeup]
+ [corner={right,top},location={left},y=.4\textheight]
+ [frame=off,
+ foregroundcolor=MainColor,
+ width=\textwidth,
+ align=left]
+ {\definedfont[Regular sa 2.5]\setupinterlinespace
+ \startmode[atpragma]
+ \strut \ConTeXt\ magazine \#\getvariable{magazine}{number}\endgraf
+ \stopmode
+ \strut \getvariable{magazine}{date} \endgraf
+ \blank
+ \strut \getvariable{magazine}{title}\endgraf
+ \doifsomething{\getvariable{magazine}{author}}
+ {\strut \getvariable{magazine}{author}\endgraf}
+ \doifsomething{\getvariable{magazine}{affiliation}}
+ {\strut \getvariable{magazine}{affiliation}\endgraf}}
+
+ \setlayerframed
+ [makeup]
+ [corner={right,bottom},location={left,top}]
+ [frame=off,
+ align=normal,
+ width=.8\textwidth,
+ foregroundcolor=MainColor]
+ {\getbuffer[abstract]}
+
+ \flushlayer[makeup]
+
+ \stopstandardmakeup
+
+ \setuplayout[reset]
+
+\stopsetups
+
+\startsetups[listing]
+
+ \page \disablemode[frame]
+
+ \setuptexttexts [][] \setuptexttexts []
+ \setupheadertexts[][] \setupheadertexts[source code of this document]
+ \setupfootertexts[][] \setupfootertexts[]
+
+ \start \dontcomplain
+
+ \typefile[TEX]{\inputfilename}
+
+ \stop
+
+\stopsetups
+
+\startsetups[lastpage]
+
+ \page \disablemode[frame] \page[even]
+
+ \doifoddpageelse
+ {}
+ {\setuplayout[makeup]
+ \startstandardmakeup[doublesided=no,page=]
+ \stopstandardmakeup
+ \setuplayout[reset]}
+
+\stopsetups
+
+\startsetups[title]
+
+ \disablemode[frame]
+
+ \setlayerframed
+ [title]
+ [corner={left,top},location={left,bottom},
+ rotation=90]
+ [frame=off,
+ foregroundcolor=MainColor]
+ {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}}
+
+ \setlayerframed
+ [title]
+ [corner={right,top},
+ rotation=270]
+ [frame=off,
+ foregroundcolor=MainColor]
+ {\definedfont[RegularBold sa 2]\strut\getvariable{magazine}{title}}
+
+\stopsetups
+
+\startbuffer[abstract]
+ % no abstract
+\stopbuffer
+
+\setuphead
+ [chapter]
+ [page=yes,
+ after={\blank[2*big]},
+ color=MainColor,
+ style=\bfc]
+
+\setuphead
+ [section]
+ [before={\blank[2*big]},
+ after=\blank,
+ color=MainColor,
+ style=\bfb]
+
+\setuphead
+ [subsection]
+ [before=\blank,
+ after=,
+ color=MainColor,
+ style=\bf]
+
+\setupwhitespace
+ [big]
+
+\definetyping[xtyping] [style=\ttx]
+\definetyping[xxtyping][style=\ttxx]
+
+\definetypeface
+ [narrowtt] [tt]
+ [mono] [modern-cond] [default] [encoding=\defaultencoding]
+
+\definetyping[ntyping] \setuptyping[ntyping][style=\narrowtt]
+\definetype [ntype] \setuptype [ntype] [style=\narrowtt]
+
+\doifnotmode{demo}{\endinput}
+
+% \usemodule[mag-01]
+
+\setvariables
+ [magazine]
+ [title={Introduction},
+ author=Hans Hagen,
+ affiliation=PRAGMA ADE,
+ date=Januari 2003,
+ number=0]
+
+\startbuffer[abstract]
+ This is the zero issue of a semi periodical. The
+ associated style can be used by \CONTEXT\ users to
+ typeset and publish their own issues.
+\stopbuffer
+
+\starttext \setups [titlepage] \setups [title]
+
+\setupheadertexts[welcome]
+
+This is the zero issue of a range of \CONTEXT\ related
+publications, in most cases short introductions to new
+functionality. The style may be used by users for providing
+similar documents, but preferably not for other purposes,
+since it may confuse readers in their expectations.
+
+We've chosen a layout which is more functional than
+beautiful. This layout provides several text areas: headers
+and footers, margins and edges as well as a main text area.
+The surrounding (gray) makes the main page (which is
+slightly smaller than A4) stand out and is suitable for
+viewing in spread mode.
+
+The documents produced at \PRAGMA\ are called {\bf This
+Way}, user documents gets the title {\bf My Way}. The
+\PRAGMA\ issues are numbered. We strongly advise you not to
+use the \type {mag-} prefix for your issues, since this may
+lead to clashes with files distributed by \PRAGMA.
+
+\setups [listing]
+
+\setups [lastpage]
+
+\stoptext
diff --git a/tex/context/modules/common/s-mod.ctx b/tex/context/modules/common/s-mod.ctx
new file mode 100644
index 000000000..09ecf714c
--- /dev/null
+++ b/tex/context/modules/common/s-mod.ctx
@@ -0,0 +1,24 @@
+<?xml version='1.0' standalone='yes'?>
+
+<ctx:job>
+ <ctx:message>TeX Documentation Generator</ctx:message>
+ <ctx:preprocess>
+ <ctx:processors>
+ <ctx:processor name='ted'>mtxrun --script modules --convert --prep <ctx:value name='old'/></ctx:processor>
+ </ctx:processors>
+ <ctx:files>
+ <ctx:file processor='ted'><ctx:value name='old'/></ctx:file>
+ </ctx:files>
+ </ctx:preprocess>
+ <ctx:flags>
+ <ctx:flag>global</ctx:flag>
+ <ctx:flag>prep</ctx:flag>
+ <ctx:flag>purge</ctx:flag>
+ </ctx:flags>
+ <ctx:process>
+ <ctx:resources>
+ <ctx:module>mod-01</ctx:module>
+ </ctx:resources>
+ </ctx:process>
+</ctx:job>
+
diff --git a/tex/context/modules/common/s-pre-00.tex b/tex/context/modules/common/s-pre-00.tex
new file mode 100644
index 000000000..7f217d5bb
--- /dev/null
+++ b/tex/context/modules/common/s-pre-00.tex
@@ -0,0 +1,202 @@
+%D \module
+%D [ file=s-pre-00,
+%D version=1997.07.22,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 0,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module provides some non core functionality that can
+%D be used in the presentations styles. This module contains
+%D experimental macros.
+%D
+%D The presentation environments are independent of each other.
+%D Although they have much in common, and in many cases can be
+%D exchanged, the common components are not collected in this
+%D file. That way they can serve as examples of style
+%D definitions.
+
+\unprotect
+
+\newbox \presentationstack
+\newcounter \presentationcounter
+\newdimen \presentationheight
+
+\appendtoks\doglobal\newcounter\presentationcounter\to\everyshipout
+
+\defineframedtext
+ [presentationshield]
+
+\setupframedtexts
+ [presentationshield]
+ [\c!background=\v!color,
+ \c!backgroundcolor=StepColor,
+ \c!offset=\v!overlay,
+ \c!frame=\v!off]
+
+\definecolor[StepColor][white]
+
+\def\enablepresentationstep%
+ {\let\enablepresentationstep\relax
+ \useJSpreamblenow{presentation}%
+ \setuptexttexts
+ [\vbox to \textheight
+ {\dopresentationstep1\box\presentationstack\vfill}]}
+
+\def\presentationstep
+ {\dopresentationstep0}
+
+\def\dopresentationstep#1% not ok yet
+ {\global\setbox\presentationstack=\vbox
+ {\ifnum\presentationcounter=0
+ \global\presentationheight=\!!zeropoint
+ \fi
+ \ifcase#1\relax
+ \scratchdimen=\pagetotal
+ \else
+ \scratchdimen=\textheight
+ \fi
+ \advance\scratchdimen by -\presentationheight
+ \edef\presentationstepheight{\the\scratchdimen}
+ \global\presentationheight=\pagetotal
+ \forgetall
+ \offinterlineskip
+ \dontcomplain
+ \box\presentationstack
+ \doglobal\increment\presentationcounter
+ \scratchcounter=\realpageno \multiply\scratchcounter by 100
+ \advance\scratchcounter by \presentationcounter
+ \edef\presentationtag{presentation:\the\scratchcounter}
+ \setupfield
+ [presentation]
+ [\c!width=\v!fit,\c!height=\v!fit,\c!offset=\v!overlay,
+ \c!strut=\v!no,\c!frame=\v!off,\c!option=\v!readonly]
+ \definesymbol
+ [\presentationtag]
+ [\presentationshade]
+ \def\presentationshade
+ {\presentationshield
+ [\c!width=\textwidth,\c!height=\presentationstepheight]{}}
+ \definefield[\presentationtag][check][presentation][\presentationtag,\v!none][\presentationtag]
+ \fitfield[\presentationtag]}}
+
+\startJSpreamble {presentation} used later
+ var presentation = new Array() ;
+ for (i=1;i<=\lastpage;i++)
+ { presentation[i] = 0 }
+ this.dirty = false ;
+ function NextPresentation (pagenumber)
+ { % ++presentation[pagenumber] ;
+ presentation[pagenumber] = presentation[pagenumber] + 1 ;
+ var dummy = 100*pagenumber + presentation[pagenumber] ;
+ var v = this.getField("presentation:"+dummy) ;
+ if (v)
+ { v.hidden = true }
+ % { v.display = display.hidden }
+ else
+ { ++pagenumber ;
+ if (pagenumber<=\lastpage)
+ { presentation[pagenumber] = presentation[pagenumber] + 1 ;
+ dummy = 100*(pagenumber) + presentation[pagenumber] ;
+ v = this.getField("presentation:"+dummy) ;
+ if (v) { v.hidden = true }
+ % if (v) { v.display = display.hidden }
+ ++this.pageNum } }
+ this.dirty = false }
+\stopJSpreamble
+
+\definereference[NextStep][JS(NextPresentation{\realfolio})]
+
+%D \macros
+%D {presentationstep}
+%D
+%D The macro \type {\presentationstep} provides a basic slide
+%D show functionality. It sort of records pieces of the page
+%D that will show up stepwise. It can be used like:
+%D
+%D \starttyping
+%D \startitemize
+%D \item eerste
+%D \item tweede
+%D \stopitemize
+%D
+%D \presentationstep
+%D
+%D \startformula
+%D ax^2+bx+c
+%D \stopformula
+%D
+%D \presentationstep
+%D \stoptyping
+%D
+%D When the document is opened, the two text fragments are
+%D covered by a shield. Each page has its own shield stack. The
+%D logical reference \type {NextStep} can be used to hide the
+%D shield.
+%D
+%D \starttyping
+%D \setupfootertexts[{\button{Show Up}[NextStep]}]
+%D \stoptyping
+%D
+%D In case of presentation style 2, you can say:
+%D
+%D \starttyping
+%D \definereference[Whatever][JS(NextPresentation{\realfolio})]
+%D \stoptyping
+%D
+%D Depending of the viewer, you need to reset the fields at
+%D startup:
+%D
+%D \starttyping
+%D \setupinteraction[openaction=ResetForm]
+%D \stoptyping
+%D
+%D Fixed spacing give you the best results:
+%D
+%D \starttyping
+%D \setupwhitespace[fixed]
+%D \setupblank[fixed]
+%D \stoptyping
+%D
+%D Sometimes you need to set the color of the background, as
+%D with style 2:
+%D
+%D \starttyping
+%D \definecolor[StepColor][Page]
+%D \stoptyping
+%D
+%D Special effects can be reached with:
+%D
+%D \starttyping
+%D \setupframedtexts
+%D [presentationshield]
+%D [background=color,backgroundcolor=red]
+%D \stoptyping
+%D
+%D There is also:
+%D
+%D \starttyping
+%D \autopresentationsteptrue
+%D \stoptyping
+%D
+%D One can enable this feature as \type {step} mode.
+
+\newif\ifautopresentationstep
+
+\appendtoks \ifautopresentationstep\presentationstep\fi \to \everypar
+
+\doifmode{step} {\enablepresentationstep}
+\doifmode{autostep}{\autopresentationsteptrue\enablepresentationstep}
+
+%D When in \type {comment} mode, embedded page comments are
+%D processed and put below the page. The default space of
+%D 5cm should be adequate but can of course be changed.
+
+\doifmode{comment}{\setuppagecomment[state=start,location=bottom]}
+
+\protect \endinput
diff --git a/tex/context/modules/common/s-pre-01.tex b/tex/context/modules/common/s-pre-01.tex
new file mode 100644
index 000000000..89c5642f9
--- /dev/null
+++ b/tex/context/modules/common/s-pre-01.tex
@@ -0,0 +1,404 @@
+%D \module
+%D [ file=s-pre-01,
+%D version=1997.07.22,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 1,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This environment can be used to typeset interactive
+%D presentations. This module was first used at the 1997 \TUG\
+%D meeting.
+
+\usemodule[pre-general]
+
+%D \macros
+%D {language}
+%D
+%D Because this module is defined in english, we default to the
+%D english hyphenation patterns and labels too.
+
+\language
+ [en]
+
+%D \macros
+%D {setupbodyfont,setuplayout}
+%D
+%D For screen reading, a Lucida Bright font looks nice. We use
+%D a 14.4 point bodyfont for the main text, but switch back to
+%D 12 points for ornaments.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+\setuplayout
+ [style=smallbodyfont]
+
+%D \macros
+%D {setupcolors,definecolor}
+%D
+%D Screen presentations without color just look dull, so we
+%D enable color support. We define ourselves a yellowish
+%D backgroundcolor and a not too dark blue interactioncolor.
+
+\setupcolors
+ [state=start]
+
+\definecolor [BackgroundColor] [r=1, g=1, b=.7]
+\definecolor [InteractionColor] [r=.1, g=.5, b=.8]
+\definecolor [ContrastColor] [r=.9, g=.5, b=.2]
+
+%D \macros
+%D {setuppapersize,setuplayout,setupinteractionscreen}
+%D
+%D
+%D We use a nice large screen, and dedicate the right edge and
+%D bottom part to navigational tools. We automatically set
+%D the width and height of the page and start up full screen.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=12pt,
+ header=0pt,
+ footer=0pt,
+ height=402pt, % 450 - 12 - 15 - 12 - 12 + 3
+ bottomdistance=15pt,
+ bottom=12pt,
+ backspace=12pt,
+ margin=0pt,
+ width=fit,
+ edgedistance=12pt,
+ rightedge=96pt]
+
+\setupinteractionscreen
+ [option=max]
+
+%D \macros
+%D {setupbackgrounds}
+%D
+%D We set the pagecolor to yellow except the part of the screen
+%D that is used to display the running text. By seting the
+%D offset to 3pt the text will not touch the yellow parts. We
+%D do not set the depth.
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=BackgroundColor,
+ offset=3pt]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundcolor=white]
+
+%D I considered the next setup too, but finaly decided to
+%D comment it out.
+%D
+%D \starttyping
+%D \setupbackgrounds
+%D [bottom][text]
+%D [frame=on,
+%D framecolor=white]
+%D \stoptyping
+
+%D \macros
+%D {setupinteraction}
+%D
+%D We did not enable interactive text support yet, so let's do
+%D that now. We force page reference to circumvent problems
+%D with named destinations in buggy viewers.
+
+\setupinteraction
+ [page=yes,
+ color=InteractionColor,
+ contrastcolor=ContrastColor,
+ menu=on,
+ state=start]
+
+%D \macros
+%D {setupinteractionmenu,startinteractionmenu}
+%D
+%D At the bottom of the screen we show two navigational bars.
+%D At the left we show the subpage bar, at the right we use a
+%D non default backward|/|forward bar.
+
+\setupinteractionmenu
+ [bottom]
+ [leftoffset=-3pt,
+ rightoffset=-3pt]
+
+\startinteractionmenu[bottom]
+ \txt \InteractionBar \\
+ \txt \InteractionButtons \\
+\stopinteractionmenu
+
+%D \macros
+%D {interactionbar}
+%D
+%D The left bar gets a white border (on the yellow background).
+%D Because we don't want to typeset an empty frame when no
+%D subpage bar is shown, we check for the number of subpages.
+
+\def\InteractionBar%
+ {\ifnum\nofsubpages>1
+ \framed
+ [framecolor=white,rulethickness=1pt,
+ height=\bottomheight,strut=no]
+ {\interactionbar[alternative=f,width=.5\makeupwidth,height=1ex]}
+ \fi}
+
+%D \macros
+%D {setupinteractionbar, interactionbuttons}
+%D
+%D The right hand buttons enable us to jump backward and forward,
+%D as well as to the previous and next jump. We also enable to
+%D close the presentation.
+
+\setupinteractionbar
+ [framecolor=white,rulethickness=1pt,
+ height=\bottomheight,strut=no]
+
+\def\InteractionButtons%
+ {\interactionbuttons
+ [width=15em]
+ [PreviousJump,NextJump,
+ firstpage,
+ firstsubpage,previouspage,nextpage,lastsubpage,
+ lastpage,
+ CloseDocument]}
+
+%D \macros
+%D {StartTitlePage, TitlePage}
+%D
+%D The titlepage is rather simple and can be typeset in two
+%D ways:
+%D
+%D \starttyping
+%D \StartTitlePage
+%D text \\ text \\ text
+%D \StopTitlepage
+%D \stoptyping
+%D
+%D or more straightforward:
+%D
+%D \starttyping
+%D \TitlePage{text\\text\\text}
+%D \stoptyping
+%D
+%D The first alternative can be used for more complicated
+%D title pages.
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \let\\=\vfil}
+
+\def\StopTitlePage%
+ {\vfil\vfil\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D \macros
+%D {TitlePage, Topics, Topic, Subject}
+%D
+%D A presentation after loading this module looks like:
+%D
+%D \starttyping
+%D \TitlePage {About Whatever\\Topics}
+%D
+%D \Topics {Todays Talk}
+%D
+%D \Topic {Some topic}
+%D
+%D \Subject {Alfa}
+%D
+%D .....
+%D
+%D \Subject {Beta}
+%D
+%D .....
+%D \stoptyping
+
+%D \macros
+%D {definehead}
+%D
+%D The commands \type{\Topic} and \type{\Subject} are defined
+%D as copies of head. We use \type{\Nopic} for internal
+%D purposes.
+
+\definehead [Topic] [chapter]
+\definehead [Subject] [section]
+
+\definehead [Nopic] [title]
+
+%D \macros
+%D {setuphead}
+%D
+%D Because chapters and sections do not make sense in
+%D presentations, we use our own command for typesetting the
+%D titles. Sectionnumbers are of course hidden from viewing.
+%D Each topic is followed by a list of subjects that belong
+%D to the topic.
+
+\setuphead
+ [Topic, Nopic, Subject]
+ [command=\HeadLine,
+ page=yes,
+ style=\tfb,
+ after=\blank,
+ sectionnumber=no]
+
+\setuphead
+ [Topic]
+ [after=\PlaceSubjectList]
+
+\setuphead
+ [Subject]
+ [continue=no]
+
+%D \macros
+%D {framed, midalined}
+%D
+%D The command used to typeset the head lines is rather simple.
+%D We just center the framed title. The frame macro optimizes
+%D the alignment and at the same time enables us to typeset a
+%D nice colored rule.
+
+\def\HeadLine#1#2%
+ {\midaligned
+ {\framed
+ [framecolor=BackgroundColor,rulethickness=1pt,
+ width=.8\hsize,align=middle,strut=no]
+ {#2}}}
+
+%D \macros
+%D {setuplist}
+%D
+%D The subject list is automatically placed. We center each
+%D subject line by using one of the default alternatives (g). We
+%D could have said:
+%D
+%D \starttyping
+%D \setuplist
+%D [Subject]
+%D [alternative=none,
+%D command=\SubjectListLine,
+%D interaction=all]
+%D
+%D \def\SubjectListLine#1#2#3%
+%D {\midaligned{#2}}
+%D \stoptyping
+%D
+%D But why should we complicate things when we can use
+%D alternative~\type{g}. The test is only needed if one
+%D does not automatically goes a new page with each subject.
+
+\def\PlaceSubjectList%
+ {\blank
+ \determinelistcharacteristics[Subject]
+ % \ifnum\utilitylistlength>0 \placelist[Subject] \fi}
+ \doifmode{*list}{\placelist[Subject]}}
+
+\setuplist
+ [Subject, Topic]
+ [alternative=g,
+ interaction=all,
+ before=,
+ after=]
+
+% %D \macros
+% %D {setuptexttexts}
+% %D
+% %D The topics will be listed in the right edge, using:
+%
+% \setuptexttexts
+% [edge]
+% [][\TopicList]
+
+%D \macros
+%D {setuplist, placelist,startinteractionmenu}
+%D
+%D The actual topic list is typeset using a \type{\vbox}. We
+%D have to specify \type{criteriumcriterium=all} because otherwise no
+%D list will be typeset. (By default lists are typeset
+%D locally.)
+
+\startinteractionmenu[right]
+ \placelist
+ [Topic]
+ [alternative=f, % command, % none,
+ maxwidth=\hsize,
+ width=\hsize,
+ offset=0pt,
+ criterium=all,
+ align=left,
+ style=\setsmallbodyfont\bfx]
+\stopinteractionmenu
+
+\def\Topics#1% temporary hack
+ {\Nopic{#1}
+ \placelist[Topic][criterium=all]}
+
+\def\Subjects%
+ {}
+
+%D \macros
+%D {setuptexttexts, button}
+%D
+%D During a presentation, we want to use the cursor to point to
+%D parts of the text. Furthermore we want to be able to jump to
+%D the next page, without the need to move the cursor on buttons.
+%D Therefore we make the text part of the screen into an
+%D invisible button.
+
+\setuptexttexts
+ [\GotoNextPage][]
+
+\def\GotoNextPage
+ {\button[width=\hsize,height=\vsize,frame=off]{}[nextpage]}
+
+%D \macros
+%D {setupsubpagenumber}
+%D
+%D The left bottom navigation bar shows the subpages, which will
+%D be counted by text. One can change this in the preentation
+%D itself by saying \type {[way=byTopic]}.
+
+\setupsubpagenumber
+ [way=bytext, % Topic,
+ state=start]
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-original}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-02.tex b/tex/context/modules/common/s-pre-02.tex
new file mode 100644
index 000000000..d7a6fe458
--- /dev/null
+++ b/tex/context/modules/common/s-pre-02.tex
@@ -0,0 +1,381 @@
+%D \module
+%D [ file=s-pre-02,
+%D version=1998.04.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 2,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This environment can be used to typeset interactive
+%D presentations. This module was first used at the 1998
+%D publishers conference of the European Portable Document
+%D Association (now merged into a graphics association).
+
+\usemodule[pre-general]
+
+%D \macros
+%D {setupbodyfont, switchtobodyfont, setuplayout}
+%D
+%D At \PRAGMA\ we prefer using the Lucida Bright fonts, but
+%D one can of course load another typeface.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+\setuplayout
+ [style=smallbodyfont]
+
+%D \macros
+%D {setuppapersize, setuplayout}
+%D
+%D The papersize suits the screen dimensions. The layout is
+%D rather simple. We use the whole width of the screen and only
+%D have navigational tools at the bottom of the screen.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [backspace=1cm,
+ topspace=1cm,
+ margin=0pt,
+ header=0pt,
+ footer=0pt,
+ bottomdistance=.875cm,
+ bottom=1cm,
+ width=fit,
+ height=fit]
+
+%D \macros
+%D {setupwhitespace, setuptyping}
+%D
+%D We don't have much height, so we use a more cramped
+%D spacing. Verbatim text looks better when indented.
+%D
+
+\setupwhitespace
+ [medium]
+
+\setuptyping
+ [margin=standard]
+
+%D \macros
+%D {definecolor, setupcolors}
+%D
+%D Of course we enable color. We define some logical colors,
+%D of which most default to the same green shade.
+
+\definecolor [BackgroundColor] [r=.8, g=.8, b=.8]
+\definecolor [OrnamentColor] [r= 0, g=.7, b=.4]
+
+\setupcolors
+ [state=start]
+
+%D \macros
+%D {setupinteraction, setupinteractionscreen}
+%D
+%D We still have to enable interaction mode. We go full
+%D screen!
+
+\setupinteraction
+ [state=start,
+ color=OrnamentColor,
+ contrastcolor=OrnamentColor]
+
+\setupinteractionscreen
+ [option=max,
+ width=fit,
+ height=fit]
+
+%D \macros
+%D {setupitemize}
+%D
+%D And why not bring some color in itemizations too?
+
+\setupitemize
+ [color=OrnamentColor]
+
+%D \macros
+%D {defineoverlay, setupbackgrounds}
+%D
+%D The navigational elements and the backgrounds are
+%D provided by \METAPOST.
+%D
+%D When \METAPOST\ is used, it makes sense to generate the
+%D graphics at runtime. This is supported when one enables
+%D system calls in the local \type {texmf.cnf} file and add the
+%D switch \type {\runMPgraphicstrue} to the local file \type
+%D {cont-sys.tex}. When direct processing is disabled or not
+%D supported, \TEXEXEC\ will take care of graphic generation.
+
+\startuniqueMPgraphic{PageBackground}
+ fill unitsquare
+ xyscaled(OverlayWidth,OverlayHeight)
+ withcolor OverlayColor ;
+ draw unitsquare
+ xyscaled(OverlayWidth,OverlayHeight)
+ enlarged (-2*OverlayLineWidth)
+ withpen pencircle scaled OverlayLineWidth
+ withcolor OverlayLineColor ;
+\stopuniqueMPgraphic
+
+\defineoverlay
+ [PageBackground]
+ [\uniqueMPgraphic{PageBackground}]
+
+\setupbackgrounds
+ [page]
+ [background=PageBackground,
+ backgroundcolor=BackgroundColor,
+ rulethickness=.125cm,
+ framecolor=OrnamentColor]
+
+%D \macros
+%D {setuptexttexts}
+%D
+%D By clicking on the text area, one goes to the next page.
+%D We hook this feature into the text backgrounds.
+
+\startuniqueMPgraphic{TextBackground}
+ draw unitsquare
+ xyscaled(OverlayWidth,OverlayHeight)
+ enlarged (4*OverlayLineWidth)
+ withpen pencircle scaled OverlayLineWidth
+ withcolor OverlayLineColor ;
+\stopuniqueMPgraphic
+
+\defineoverlay
+ [TextBackground]
+ [\uniqueMPgraphic{TextBackground}]
+
+\defineoverlay
+ [NextPage]
+ [\overlaybutton{nextpage}]
+
+\setupbackgrounds
+ [text]
+ [background={TextBackground,NextPage},
+ backgroundcolor=BackgroundColor,
+ rulethickness=.0625cm,
+ framecolor=OrnamentColor]
+
+%D \macros
+%D {setupinteractionmenu,startinteractionmenu}
+%D
+%D At the bottom of the screen, we show three buttons. These
+%D direct us to the previous or next jump or exit the document.
+
+\setupMPvariables[RightArrow][height=\bottomheight]
+\setupMPvariables[LeftArrow] [height=\bottomheight]
+\setupMPvariables[Circle] [height=\bottomheight]
+\setupMPvariables[UpArrow] [height=\bottomheight]
+
+\startuniqueMPgraphic{RightArrow}{height}
+ z1=(0,0) ; z2=(\MPvar{height},.5y3) ; z3=(0,\MPvar{height}) ;
+ drawfill z1--z2--z3--cycle
+ withpen pencircle scaled (\MPvar{height}/5)
+ withcolor \MPcolor{OrnamentColor} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{LeftArrow}{height}
+ z1=(\MPvar{height},0) ; z2=(0,.5y3) ; z3=(\MPvar{height},\MPvar{height}) ;
+ drawfill z1--z2--z3--cycle
+ withpen pencircle scaled (\MPvar{height}/5)
+ withcolor \MPcolor{OrnamentColor} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{Circle}{height}
+ drawfill fullcircle scaled \MPvar{height}
+ withpen pencircle scaled (\MPvar{height}/5)
+ withcolor \MPcolor{OrnamentColor} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{UpArrow}{height}
+ z1=(0,0) ; z2=(\MPvar{height},0) ; z3=(.5x2,\MPvar{height}) ;
+ drawfill z1--z2--z3--cycle
+ withpen pencircle scaled (\MPvar{height}/5)
+ withcolor \MPcolor{OrnamentColor} ;
+\stopuniqueMPgraphic
+
+\setupinteractionmenu
+ [bottom]
+ [state=start,
+ frame=off,
+ width=.3\textwidth,
+ height=\bottomheight]
+
+\setupinteraction
+ [menu=on]
+
+\def\WhateverButton
+ {\doifreferencefoundelse{Whatever}
+ {\raw [Whatever] \uniqueMPgraphic{UpArrow} \\}
+ {}}
+
+\startinteractionmenu[bottom]
+ \but [Topics] \\ % secret button
+ \hfill
+ \WhateverButton % user specific
+ \kern2\bottomheight
+ \raw [previouspage] \uniqueMPgraphic{LeftArrow} \\
+ \kern.5\bottomheight
+ \raw [CloseDocument] \uniqueMPgraphic{Circle} \\
+ \kern.5\bottomheight
+ \raw [nextpage] \uniqueMPgraphic{RightArrow} \\
+ \kern.5\bottomheight
+\stopinteractionmenu
+
+%D \macros
+%D {TitlePage, Topics, Topic, Subject}
+%D
+%D A presentation after loading this module looks like:
+%D
+%D \starttyping
+%D \TitlePage {About Whatever\\Topics}
+%D
+%D \Topics {Todays Talk}
+%D
+%D \Topic {Some topic}
+%D
+%D .....
+%D
+%D \Topic {Next Topic}
+%D
+%D .....
+%D \stoptyping
+
+%D \macros
+%D {StartTitlePage, TitlePage}
+%D
+%D The titlepage is rather simple and can be typeset in two
+%D ways:
+%D
+%D \starttyping
+%D \StartTitlePage
+%D text \\ text \\ text
+%D \StopTitlepage
+%D \stoptyping
+%D
+%D or as one||liner:
+%D
+%D \starttyping
+%D \TitlePage{text\\text\\text}
+%D \stoptyping
+%D
+%D The first alternative can be used for more complicated
+%D title pages.
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \let\\=\vfil}
+
+\def\StopTitlePage%
+ {\vfil\vfil\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D \macros
+%D {definehead}
+%D
+%D The commands \type{\Topic} and \type{\Subject} are defined
+%D as copies of head. We use \type{\Nopic} for internal
+%D purposes.
+
+\definehead [Topic] [chapter]
+\definehead [Subject] [section]
+
+\definehead [Nopic] [title]
+
+%D \macros
+%D {setuphead}
+%D
+%D We use our own command for typesetting the titles. We hide
+%D sectionnumbers from viewing. Each topic is followed by a
+%D list of subjects that belong to the topic.
+
+\setuphead
+ [Topic, Nopic]
+ [after={\blank[3*medium]},
+ number=no,
+ style=\tfb,
+ page=yes,
+ alternative=middle]
+
+\setuphead
+ [Subject]
+ [after=\blank,
+ number=no,
+ page=yes,
+ continue=no,
+ style=\tfa]
+
+%D \macros
+%D {setuplist}
+%D
+%D When found, the subject list is automatically placed
+%D after the topic head.
+
+\setuplist
+ [Topic,Subject]
+ [alternative=g,
+ interaction=all,
+ before=,
+ after=]
+
+\setuplist
+ [Topic]
+ [criterium=all]
+
+\def\Topics#1%
+ {\determinelistcharacteristics[Topic]
+ \doifmode{*list}
+ {\Nopic[Topics]{#1}
+ \startcolumns
+ \placelist[Topic]
+ \stopcolumns}}
+
+\setuplist
+ [Subject]
+ [criterium=Topic]
+
+\def\Subjects%
+ {\determinelistcharacteristics[Subject]
+ \doifmode{*list}
+ {\placelist[Subject]}}
+
+\setuphead
+ [Topic]
+ [after={\blank[3*medium]\Subjects}]
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-green}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-03.tex b/tex/context/modules/common/s-pre-03.tex
new file mode 100644
index 000000000..19a11d24e
--- /dev/null
+++ b/tex/context/modules/common/s-pre-03.tex
@@ -0,0 +1,257 @@
+%D \module
+%D [ file=s-pre-03,
+%D version=1998.09.06,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 3,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is the third environment for typesetting interactive
+%D presentations. I used this style for a talk on \TEX\ and
+%D \JAVASCRIPT\ at \TUG98, mainly because I didn't want to
+%D use the same style three times. Therefore this is a rather
+%D simple, silly style.
+
+\usemodule[pre-general]
+
+%D \macros
+%D {setupbodyfont}
+%D
+%D We use a large bodyfont. Combined with the fancy
+%D background, this does not leave that much room for text, but
+%D presentations should use much text anyway.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+%D \macros
+%D {setuppapersize,setuplayout,setupinteractionscreen}
+%D
+%D The page dimensions are set to size \type {S6}, being
+%D 600pt by 450pt. We use wide margins and discard headers
+%D and footers. We also launch the document full screen.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ topspace=75pt,
+ backspace=100pt,
+ header=0pt,
+ footer=0pt]
+
+\setupinteractionscreen
+ [option=max]
+
+%D \macros
+%D {setupcolors,definecolor}
+%D
+%D Next, color support is turned on and a dark red color is
+%D defined. Other red shades will be derived from this one
+%D color.
+
+\setupcolors
+ [state=start]
+
+\definecolor [PageColor] [black]
+\definecolor [BackgroundColor] [s=.85]
+\definecolor [OrnamentColor] [r=.75]
+
+%D \macros
+%D {setupinteraction}
+%D
+%D We turn on interaction mode and use the same color for
+%D hyperlinks and redundant hyperlinks (the ones that point
+%D to the current page).
+
+\setupinteraction
+ [state=start,
+ contrastcolor=OrnamentColor,
+ color=OrnamentColor]
+
+%D \macros
+%D {defineoverlay, setupbackgrounds}
+%D
+%D The joke in this presentation is the elliptical shape of
+%D which the bottom part includes a page indication.
+
+\defineoverlay
+ [PageShape][\useMPgraphic{PageShape}]
+
+% \startuseMPgraphic{PageShape}
+% lin := 20pt ; off := .75lin ;
+% wid := \overlaywidth ; hei := \overlayheight ;
+% pos := \currentpage ; tot := \lastpage ;
+% path bb; bb := unitsquare xscaled wid yscaled hei ;
+% filldraw bb withcolor \MPcolor{PageColor} ;
+% pickup pencircle xscaled .5lin yscaled lin rotated 45 ;
+% pair r, t, l, b ;
+% r := (wid-off,.5hei) ; t := (.5wid,hei-off) ;
+% l := (off,.5hei) ; b := (.5wid,off) ;
+% path p; p := superellipse(r,t,l,b,.8) ;
+% fill p withcolor \MPcolor{Backgroundcolor} ;
+% draw p withcolor \MPcolor{OrnamentColor} ;
+% color contrastcolor ; contrastcolor = 2/3 * \MPcolor{OrnamentColor} ;
+% if (pos>0) and (tot>0):
+% pair pa ; pa := point 5 of p ;
+% pair pb ; pb := point 7 of p ;
+% draw pa withcolor contrastcolor ;
+% draw pb withcolor contrastcolor ;
+% len := 2/tot ;
+% pair pa ; pa := point (5+len*pos) of p ;
+% pair pb ; pb := point (5+len*(pos-1)) of p ;
+% p := p cutafter pa ;
+% p := p cutbefore pb ;
+% draw p withcolor contrastcolor ;
+% fi ;
+% setbounds currentpicture to bb ;
+% \stopuseMPgraphic
+
+\startuseMPgraphic{PageShape}
+ StartPage ;
+ path p ; pair pa, pb ; numeric len ; color contrastcolor ;
+ fill Page withcolor \MPcolor {PageColor} ;
+ pickup pencircle rotated 45 xscaled 10pt yscaled 20pt ;
+ p := Page enlarged (-10pt,-15pt) superellipsed .8 ;
+ p := p shifted (-1.5pt,0) ; % looks better
+ fill p withcolor \MPcolor{BackgroundColor} ;
+ draw p withcolor \MPcolor{OrnamentColor} ;
+ contrastcolor = 2/3 * \MPcolor{OrnamentColor} ;
+ if (PageNumber>0) and (NOfPages>0):
+ draw point 5 of p withcolor contrastcolor ;
+ draw point 7 of p withcolor contrastcolor ;
+ len := 2/NOfPages ;
+ pa := point (5+len*PageNumber) of p ;
+ pb := point (5+len*(PageNumber-1)) of p ;
+ draw (p cutafter pa) cutbefore pb
+ withcolor contrastcolor ;
+ fi ;
+ StopPage ;
+\stopuseMPgraphic
+
+%D We use the viewer provided feature to go to the previous or
+%D next page.
+
+\defineoverlay[PrevButton][\overlaybutton{PreviousPage}]
+\defineoverlay[NextButton][\overlaybutton{NextPage}]
+
+\setupbackgrounds
+ [page]
+ [background={PageShape,PrevButton}]
+
+\setupbackgrounds
+ [text][text]
+ [background=NextButton]
+
+% or using hard coded next/prev pages:
+%
+% \defineoverlay[PrevButton][\overlaybutton{previouspage}]
+% \defineoverlay[NextButton][\overlaybutton{nextpage}]
+%
+% \setupbackgrounds[state=repeat]
+% \setupbackground[text][text][background=NextButton]
+%
+% or simply (using an repeated layer):
+%
+% \setupbackground[text][background=NextButton]
+
+%D \macros
+%D {definehead, setuphead}
+%D
+%D Like the other presentation styles, we use \type {\Topic}
+%D instead of \type {\chapters}. This time we don't provide
+%D an additional sectioning. So we have:
+%D
+%D \starttyping
+%D \TitlePage{How nice}
+%D
+%D \Topics{This is about ...}
+%D
+%D \Topic{The first one}
+%D
+%D \Topic{Another one}
+%D \stoptyping
+
+\definehead [Topic] [chapter]
+\definehead [Nopic] [title]
+
+\setuphead
+ [Topic,Nopic]
+ [after={\blank[3*medium]},
+ number=no,
+ style=\tfb,
+ page=yes,
+ alternative=middle]
+
+\setuplist
+ [Topic]
+ [alternative=g,
+ interaction=all,
+ before=,
+ after=]
+
+\def\Subject
+ {\Topic}
+
+%D The tables of contents is associated with \type
+%D {\Topics}.
+
+\def\Topics#1%
+ {\Nopic[Topics]{#1}
+ \placelist[Topic][criterium=all]}
+
+\def\Subjects
+ {}
+
+%D Instead of \type {\TitlePage}, one can use the pair
+%D \type {\StartTitlePage} -- \type {\StopTitlePage}:
+%D
+%D \starttyping
+%D \StartTitlePage
+%D A Self Made Title
+%D \StopTitlePage
+%D \stoptyping
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \def\\{\vfil\bfb\setupinterlinespace}}
+
+\def\StopTitlePage%
+ {\vfil\vfil\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-funny}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-04.tex b/tex/context/modules/common/s-pre-04.tex
new file mode 100644
index 000000000..088f4e510
--- /dev/null
+++ b/tex/context/modules/common/s-pre-04.tex
@@ -0,0 +1,377 @@
+%D \module
+%D [ file=s-pre-04,
+%D version=1998.09.06,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 4,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[pre-general]
+
+%D \macros
+%D {setupbodyfont}
+%D
+%D This is just another environment for typesetting interactive
+%D presentations. I wrote this module on behalf of a course I
+%D gave for the United Kingdom \TeX\ users group.
+
+\setupbodyfont[ams,pos,14.4pt]
+
+%D \macros
+%D {setupcolors,definecolor}
+%D
+%D I started using dark blue for the navigational elements. In
+%D that context, dark red is a logical choice for the contrast
+%D color. While playing around with the navigational elements
+%D I decided to use the not so dominant color yellow for the
+%D status bar.
+%D
+%D A few days before I wrote this style, the recent acquisition
+%D of Mondriaans last painting by the Dutch governement was a
+%D hot topic in the dutch news scenary. Therefore I decided to
+%D replace the rather dull title page by something more
+%D colorful, in mondriaan colors, but far more random than any
+%D of his paintings. For consistence we remap the already
+%D defined primary colors.
+
+\setupcolors [state=start]
+
+\definecolor [NoneColor] [s=.6]
+\definecolor [GotoColor] [b=.6] \definecolor[blue] [GotoColor]
+\definecolor [ExitColor] [r=.6] \definecolor[red] [ExitColor]
+\definecolor [JumpColor] [s=.6]
+\definecolor [UserColor] [g=.6] \definecolor[green] [UserColor]
+\definecolor [StepColor] [r=.6,g=.6] \definecolor[yellow][StepColor]
+
+\definecolor [PageColor] [s=.80] \definecolor[gray] [PageColor]
+\definecolor [TextColor] [s=.90]
+
+%D \macros
+%D {setuppapersize}
+%D
+%D As usual, we take a screen oriented paper size:
+
+\setuppapersize
+ [S6][S6]
+
+%D \macros
+%D {setuplayout,setupinteractionscreen}
+%D
+%D The layout definition fits into this $600\times450$ point
+%D area, but the dimensions are somewhat diffused by the text
+%D background offset.
+
+\setuplayout
+ [width=530pt,
+ height=400pt,
+ header=0pt,
+ footer=0pt,
+ backspace=15pt,
+ topspace=15pt,
+ bottomdistance=15pt,
+ bottom=10pt,
+ margin=0pt,
+ rightedgedistance=15pt,
+ rightedge=30pt]
+
+\setupinteractionscreen
+ [option=max]
+
+%D \macros
+%D {setupbackgrounds}
+%D
+%D Both the page and the text area have a gray background.
+%D The \type {[text,text]} area also has an offset. Later we
+%D will see that we have to compensate for that in the
+%D navigational areas.
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=PageColor]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundcolor=TextColor,
+ backgroundoffset=5pt]
+
+%D \macros
+%D {setupinteraction}
+%D
+%D For convenient navigation, we turn on interaction.
+
+\setupinteraction
+ [state=start,
+ menu=on,
+ color=UserColor,
+ contrastcolor=NoneColor]
+
+%D \macros
+%D {setupsubpagenumber}
+%D
+%D When navigating the document, we keep the title page out
+%D of sight, therefore we use sub page numbers.
+
+\setupsubpagenumber
+ [state=start,
+ way=bytext]
+
+%D \macros
+%D {setupinteractionmenu}
+%D
+%D There is only one interaction menu, located in the right
+%D edge of the screen. Both offsets enlarge the edge by the
+%D same amount as the text background offset.
+
+\setupinteractionmenu
+ [right]
+ [state=start,
+ frame=off,
+ strut=no,
+ offset=0pt,
+ inbetween=,
+ bottomoffset=-5pt,
+ topoffset=-5pt]
+
+%D \macros
+%D {startinteractionmenu}
+%D
+%D The menu itself is not that spectacular. We use the
+%D start||stop alternative for setting the content. The macro
+%D \type {\interactioncolor} expands into either the
+%D interaction color or the contrast color, the latter only
+%D when no jump is possible.
+
+\startinteractionmenu[right]
+ \setupinteraction[color=GotoColor]
+ \but [previoussubpage] \Triangle {90}\framedwidth\interactioncolor \\
+ \vskip10pt
+ \but [nextsubpage] \Triangle{270}\framedwidth\interactioncolor \\
+ \vfill
+ \but [PreviousJump] \Triangle{180}\framedwidth{NoneColor} \\
+ \vskip-5pt
+ \but [NextJump] \Triangle {0}\framedwidth{NoneColor} \\
+\stopinteractionmenu
+
+%D \macros
+%D {setupinteractionbar}
+%D
+%D The interaction bar at the bottom is also larger than the
+%D normal width of the bottom area.
+
+\setupinteractionbar
+ [alternative=f,
+ width=\textwidth,
+ height=\bottomheight,
+ distance=10pt,
+ color=NoneColor,
+ contrastcolor=StepColor]
+
+%D \macros
+%D {setupbottomtexts}
+%D
+%D The bar is centered in the middle.
+
+\setupbottomtexts
+ [\interactionbar]
+
+%D We can exit viewing with a close button, located on the
+%D rightmost bottom area.
+
+\def\CloseButton
+ {\button
+ [width=\rightedgewidth,height=\bottomheight,offset=overlay,
+ background=color,backgroundcolor=ExitColor,frame=off]
+ {}%
+ [CloseDocument]}
+
+\setupbottomtexts
+ [edge][][\CloseButton]
+
+%D \macros
+%D {definesymbol,setupitemize}
+%D
+%D Because some prominent things are rectangular or triangular,
+%D we prefer some different symbols in itemizations:
+
+\definesymbol[1][$\blacktriangleright$]
+\definesymbol[2][$\blacktriangledown$]
+\definesymbol[3][$\blacktriangleright$]
+\definesymbol[4][$\blacktriangledown$]
+
+\setupitemize[each][color=NoneColor]
+
+%D \macros
+%D {TitlePage,defineoverlay,button,setupalign,
+%D setupbackgrounds,setupinteraction,setupinteractionbar,
+%D startstandardmakeup,switchtobodyfont,setupinterlinespace}
+%D
+%D Now the main layout and navigational definitions are
+%D done, it makes sense to define and tune some structuring
+%D commands. First we build the titlepage.
+
+\defineoverlay [TitleGraphic] [\useMPgraphic{title}]
+\defineoverlay [NextPage] [\overlaybutton{nextpage}]
+
+\def\StartTitlePage
+ {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}]
+ \setupbackgrounds[text][text][background=]
+ \setupinteraction[menu=off]
+ \setupinteractionbar[state=stop]
+ \startstandardmakeup
+ \switchtobodyfont[24pt]
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \let\\=\vfil}
+
+\def\StopTitlePage
+ {\vfil\vfil\vfil
+ \stopstandardmakeup
+ \setupinteraction[menu=on]
+ \setupinteractionbar[state=start]
+ \setupbackgrounds[page][background=color]
+ \setupbackgrounds[text][text][background=color]
+ \setupsubpagenumber[reset]}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D \macros
+%D {Topic, Nopic, Subject,
+%D definehead, setuphead}
+%D
+%D We use \type {\Topic} and \type {\Subject} instead of
+%D chapters and sections. The \type {\Nopic} alternative is
+%D meant for internal use.
+
+\definehead [Topic] [chapter]
+\definehead [Nopic] [title]
+\definehead [Subject] [section]
+
+\setuphead
+ [Topic, Nopic]
+ [after={\blank[3*medium]},
+ number=no,
+ style=\tfb,
+ page=yes,
+ alternative=middle]
+
+\setuphead
+ [Subject]
+ [after=\blank,
+ number=no,
+ page=yes,
+ continue=no,
+ style=\tfa]
+
+%D \macros
+%D {Topics, Subjects,
+%D setuplist, placelist, startcolumns}
+%D
+%D This style is meant for the more large presentations, and
+%D therefore provided for a list of topics as well as local
+%D lists of subjects. When many topics are introduces, the
+%D list is typeset in columns.
+
+\setuplist
+ [Topic,Subject]
+ [alternative=g,
+ interaction=all,
+ before=,
+ after=]
+
+\setuplist
+ [Topic]
+ [criterium=all]
+
+\def\Topics#1%
+ {\determinelistcharacteristics[Topic]
+ \ifnum\utilitylistlength>0
+ \Nopic[Topics]{#1}
+ \ifnum\utilitylistlength>12
+ \startcolumns
+ \placelist[Topic]
+ \stopcolumns
+ \else
+ \placelist[Topic]
+ \fi
+ \fi}
+
+\def\Subjects%
+ {\placelist[Subject]}
+
+%D Last we define the overlays. Look at the way colors are
+%D linked into the macros.
+
+\startMPinclusions
+ def triangle (expr wid, rot, col) =
+ x1 := x3 := y1 := 0 ; x2 := y3 := wid ; y2 := .5y3 ;
+ fill (z1--z2--z3--cycle) rotated rot withcolor col ;
+ currentpicture := currentpicture xysized (wid,wid) ;
+ enddef ;
+\stopMPinclusions
+
+\setupMPvariables
+ [triangle]
+ [width=1cm,
+ rotation=0,
+ color=black]
+
+\startuniqueMPgraphic{triangle}{width,rotation,color}
+ triangle(\MPvar{width},\MPvar{rotation},\MPvar{color}) ;
+\stopuniqueMPgraphic
+
+\def\Triangle#1#2#3%
+ {\uniqueMPgraphic{triangle}{rotation=#1,width=#2,color=#3}}
+
+\startuseMPgraphic{title} % can be simplified with "randomized"
+ color c ; path p ;
+ for i=1 upto 250 :
+ x0 := uniformdeviate \overlaywidth ;
+ y0 := uniformdeviate \overlayheight ;
+ sx := uniformdeviate 20 ;
+ sy := uniformdeviate 20 ;
+ cc := round(uniformdeviate 2) ;
+ if cc=0 : c := \MPcolor{GotoColor} fi ;
+ if cc=1 : c := \MPcolor{ExitColor} fi ;
+ if cc=2 : c := \MPcolor{StepColor} fi ;
+ qq := round(uniformdeviate 1) ;
+ if qq=0 :
+ p := unitsquare xscaled sx yscaled sy ;
+ else :
+ rr := round(uniformdeviate 3) * 90 ;
+ x1 := x3 := y1 := 0 ; x2 := y3 := sx; y2 := .5y3 ;
+ p := (z1--z2--z3--cycle) rotated rr ;
+ fi ;
+ fill p shifted z0 withcolor c ;
+ endfor ;
+\stopuseMPgraphic
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-colorfull}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-05.tex b/tex/context/modules/common/s-pre-05.tex
new file mode 100644
index 000000000..ccffd1f4d
--- /dev/null
+++ b/tex/context/modules/common/s-pre-05.tex
@@ -0,0 +1,240 @@
+%D \module
+%D [ file=s-pre-05,
+%D version=1998.12.12,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 5,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[pre-general]
+
+%D As all styles sofar, this one has the same structuring
+%D commands.
+
+\startmode[asintended] \setupbodyfont[ludicaot] \stopmode
+
+\setupbodyfont[14.4pt]
+
+\setupcolors [state=start]
+
+\definecolor [BackgroundColor] [s=.95]
+\definecolor [OrnamentColor] [r=.6,g=.7,b=.8]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=430pt,
+ height=400pt,
+ header=0pt,
+ footer=0pt,
+ margin=0pt,
+ backspace=25pt,
+ topspace=25pt,
+ rightedgedistance=20pt,
+ rightedge=110pt]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupbackgrounds
+ [state=repeat]
+
+\setupbackgrounds
+ [page]
+ [backgroundcolor=white]
+
+\setupbackgrounds
+ [text][text]
+ [background={HashFrameA,NextPage},
+ backgroundoffset=20pt]
+
+\defineoverlay
+ [HashFrameA]
+ [\useMPgraphic{HashFrameA}]
+
+\defineoverlay
+ [HashFrameB]
+ [\useMPgraphic{HashFrameB}]
+
+\setupinteraction
+ [state=start,
+ menu=on,
+ color=OrnamentColor,
+ contrastcolor=OrnamentColor]
+
+%D Watch how we use a list alternative that matches the
+%D menu.
+
+\setupinteractionmenu
+ [right]
+ [background=HashFrameB,
+ style=smallbold,
+ frame=off,
+ offset=10pt,
+ height=35pt,
+ before=,
+ after=,
+ inbetween=\endgraf,
+ width=\rightedgewidth]
+
+\startinteractionmenu[right]
+ \placelist
+ [Topic]
+ [criterium=all,
+ alternative=right,
+ maxwidth=.8\rightedgewidth,
+ interaction=all,
+ before=,
+ after=]
+ \vfill
+ \setupinteractionmenu
+ [right]
+ [height=30pt]
+ \but [CloseDocument] Close \\
+\stopinteractionmenu
+
+\setupwhitespace
+ [big]
+
+\setupblank
+ [big]
+
+%D \macros
+%D {TitlePage}
+%D
+%D Now the main layout and navigational definitions are
+%D done, it makes sense to define and tune some structuring
+%D commands. First we build the titlepage.
+
+\defineoverlay [TitleGraphic] [\useMPgraphic{TitleGraphic}]
+\defineoverlay [NextPage] [\overlaybutton{forward}]
+
+\unexpanded\def\StartTitlePage
+ {\setupbackgrounds[page][background={color,TitleGraphic,NextPage}]
+ \setupbackgrounds[text][text][background=]
+ \setupinteraction[menu=off]
+ \setupinteractionbar[state=stop]
+ \setuplayout[width=550pt,rightedge=0pt]
+ \startstandardmakeup
+ \switchtobodyfont[24pt]
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \let\\=\vfil}
+
+\unexpanded\def\StopTitlePage
+ {\vfil\vfil\vfil
+ \stopstandardmakeup
+ \setuplayout[width=430pt,rightedge=110pt]
+ \setupinteraction[menu=on]
+ \setupinteractionbar[state=start]
+ \setupbackgrounds[page][background=color]
+ \setupbackgrounds[text][text][background={HashFrameA,NextPage}]}
+
+\unexpanded\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D \macros
+%D {Topics,Subjects}
+%D
+%D Since the lists are in the menu, we don't honor list
+%D placement macros.
+
+\unexpanded\def\Topics#1{}
+\unexpanded\def\Subjects{}
+
+%D \macros
+%D {Topic, Nopic, Subject}
+%D
+%D Since t his style is meant for rather flat structured
+%D documents, only \type {\Topic} makes sense.
+
+\definehead [Topic] [chapter]
+\definehead [Nopic] [title]
+\definehead [Subject] [section]
+
+\setuphead
+ [Topic, Nopic]
+ [after={\blank[3*medium]},
+ number=no,
+ style=\tfb,
+ page=yes,
+ alternative=middle]
+
+\setuphead
+ [Subject]
+ [after=\blank,
+ number=no,
+ page=yes,
+ continue=no,
+ style=\tfa]
+
+%D We use only one kind of base graphic, which is sligthly
+%D tuned for the different usage.
+
+\startMPinclusions
+ def random_hash_frame (expr width, height, offset, linewidth ) =
+
+ def delta = ((uniformdeviate .5offset) + .25offset) enddef ;
+ x1 := offset ; y1 := offset ; x2 := width-offset ; y2 := height-offset ;
+
+ drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{BackgroundColor}) ;
+ fill z1--(x2,y1)--z2--(x1,y2)--cycle ;
+
+ drawoptions(withpen pencircle scaled linewidth withcolor \MPcolor{OrnamentColor}) ;
+ draw (x1-delta,y1)--(x2+delta,y1) ;
+ draw (x2,y1-delta)--(x2,y2+delta) ;
+ draw (x2+delta,y2)--(x1-delta,y2) ;
+ draw (x1,y2+delta)--(x1,y1-delta) ;
+
+ drawoptions();
+ setbounds currentpicture to unitsquare xscaled width yscaled height ;
+ enddef ;
+\stopMPinclusions
+
+\startuseMPgraphic{HashFrameA}
+ random_hash_frame(OverlayWidth,OverlayHeight,15pt,2pt) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{HashFrameB}
+ random_hash_frame(OverlayWidth,OverlayHeight, 5pt,2pt) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{TitleGraphic}
+ for i=1 upto 300 :
+ offset := uniformdeviate 10pt ;
+ width := 2*offset + 30pt + uniformdeviate 30pt ;
+ height := 2*offset + 10pt + uniformdeviate 10pt ;
+ addto currentpicture also
+ image(random_hash_frame(width,height,offset,1pt)) shifted
+ (uniformdeviate OverlayWidth, uniformdeviate OverlayHeight) ;
+ endfor ;
+\stopuseMPgraphic
+
+\continueifinputfile{s-pre-05.tex}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-fuzzy}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-06.tex b/tex/context/modules/common/s-pre-06.tex
new file mode 100644
index 000000000..47948262c
--- /dev/null
+++ b/tex/context/modules/common/s-pre-06.tex
@@ -0,0 +1,324 @@
+%D \module
+%D [ file=s-pre-06,
+%D version=1999.04.28,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 6,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D I wrote this sixth presentation style on behalf of a
+%D presentation at Bachotek~'99. The joke in this style is
+%D (ab)using the Antikwa Torunska, a rather Polish font. When I
+%D was first confronted with this font, the backward slant
+%D stoke me as very characteristic.
+%D
+%D Each page has a slightly different background consisting of
+%D three O's. Although \TEX\ could do the randomization,
+%D scaling and placement, I prefered to use \METAPOST. The
+%D backward slant is also reflected in the stepwise increasing
+%D left margin. Due to this characteristic and the trick used,
+%D this style is only suited for simple presentations, using
+%D itemizations.
+
+\usemodule[pre-general]
+
+%D \macros
+%D {setupbodyfont}
+%D
+%D As said, we will use the Antikwa Torunska, and because we
+%D want it to show up well, we use it large.
+
+\setupbodyfont
+ [ant,14.4pt]
+
+%D \macros
+%D {definecolor, setupcolors}
+%D
+%D Thus style only uses gray scales, but nevertheless we turn
+%D on color. We only use a few logical color names.
+
+\setupcolors
+ [state=start]
+
+\definecolor [BackgroundColor] [s=.8]
+\definecolor [ContrastColor] [s=.9]
+\definecolor [InteractionColor] [s=.6]
+
+%D \macros
+%D {setuppapersize}
+%D
+%D As (nearly) always, we use a 600 pt times 450 pt screen
+%D width, mapped on ditto paper dimensions.
+
+\setuppapersize
+ [S6][S6]
+
+%D \macros
+%D {setuplayout}
+%D
+%D The layout is rather symmetrical. We don't use headers and
+%D footers, and thereby automatically turn off the page
+%D numbering: no room, no number. We use the bottom to present
+%D a rather trivial menu.
+
+\setuplayout
+ [backspace=2cm,
+ topspace=2cm,
+ width=middle,
+ header=0pt,
+ height=middle,
+ footer=0pt,
+ bottomdistance=.5cm,
+ bottom=1cm]
+
+%D \macros
+%D {setupinteractionmenu,startinteractionmenu}
+%D
+%D This menu is slighly moved to the right because that looks
+%D better. The menu itself has one goto (\type {\got}) entry,
+%D which is forced to the right.
+
+\setupinteractionmenu
+ [bottom]
+ [rightoffset=-1cm]
+
+\startinteractionmenu[bottom]
+ \hfill \got [CloseDocument] \bfd Quit \\
+\stopinteractionmenu
+
+%D \macros
+%D {setupbackgrounds}
+%D
+%D Page background are calculated at each page, opposite to the
+%D other backgrounds, that are reused and only calculated when
+%D \CONTEXT\ is explictly told to do so. There are three
+%D overlays: a gray fill, the graphic, and a button that
+%D circulates the pages.
+
+\setupbackgrounds
+ [page]
+ [background={color,Joke,GoAround},
+ backgroundcolor=BackgroundColor]
+
+%D \macros
+%D {defineoverlay}
+%D
+%D The \type {forward} reference action circulates over the
+%D pages, so, at the last page, we are led back to the first.
+
+\defineoverlay [GoAround] [\overlaybutton{forward}]
+
+%D The joke is a simple \METAPOST\ routine. The picture is
+%D actually larger than the screen, but is clipped of when
+%D included.
+
+\defineoverlay [Joke] [\useMPgraphic{background}]
+
+\startuseMPgraphic{background}
+ width := \overlaywidth ;
+ height := \overlayheight ;
+ picture p ; p := char 79 infont "\truefontname{Regular}" scaled 1 ;
+ pwidth := xpart urcorner bbox p - xpart llcorner bbox p ;
+ pheight := ypart urcorner bbox p - ypart llcorner bbox p ;
+ def do (expr r) =
+ addto currentpicture also p shifted - center p scaled r
+ xscaled (width/pwidth) yscaled (height/pheight)
+ withcolor \MPcolor{ContrastColor} ;
+ enddef ;
+ do (0.9+uniformdeviate0.1) ;
+ do (1.4+uniformdeviate0.1) ;
+ do (1.9+uniformdeviate0.1) ;
+\stopuseMPgraphic
+
+%D \macros
+%D {setupinteraction,setupinteractionscreen}
+%D
+%D We did not yet turn on the interaction, so let's do that
+%D now. When opened, the document will fil the screen.
+
+\setupinteraction
+ [state=start,
+ color=InteractionColor,
+ contrastcolor=InteractionColor,
+ menu=on]
+
+\setupinteractionscreen
+ [option=max]
+
+%D \macros
+%D {TitlePage, Topics, Topic}
+%D
+%D A presentation normally consists of a title page, a list of
+%D topics, and the content itself. In this style, a further
+%D subdivision does not make sense, but because we want to be
+%D compatible with the other styles, they are added. A
+%D presentation looks like:
+%D
+%D \starttyping
+%D \usemodule[pre-antikwa]
+%D
+%D \startext
+%D
+%D \TitlePage{The Title}
+%D
+%D \Topics{Contents}
+%D
+%D \Topic{Some Topic}
+%D
+%D \startitemize
+%D \item first
+%D \item second
+%D \stopitemize
+%D
+%D \Topic{Some Topic}
+%D
+%D ...
+%D
+%D \stoptext
+%D \stoptyping
+
+%D \macros
+%D {definehead, Topic, Subject}
+%D
+%D We use dedicated sectioning commands.
+
+\definehead [Topic] [chapter]
+\definehead [Subject] [section]
+
+\definehead [Nopic] [title]
+
+%D \macros
+%D {setuphead}
+%D
+%D We turn of numbering. The assignment to \type {after} takes
+%D care of the increasing indentation. This indentation is the
+%D only low level \TEX\ code needed. Including this
+%D functionality in the core of \CONTEXT\ is not that useful
+%D and I would forget about this feature being present anyway.
+
+\setuphead
+ [Topic, Nopic, Subject]
+ [number=no,
+ after={\blank[2*big]\ToTheLeft\everypar{\ToTheRight}}]
+
+%D After section titles we set the \type {\leftskip} to a value
+%D that suits the Antikwa slant.
+
+\def\ToTheLeft%
+ {\gdef\LeftSkip{30}%
+ \rightskip0pt\relax
+ \leftskip30pt\relax}
+
+%D Each new paragraph adds to the \type {\leftskip}.
+
+\def\ToTheRight%
+ {\doglobal\increment(\LeftSkip,20)%
+ \leftskip=\LeftSkip pt\relax}
+
+%D \macros
+%D {Topics}
+%D
+%D The \type {\Topics} command uses a bot of low level
+%D \CONTEXT. We could have done with:
+%D
+%D \starttyping
+%D \def\Topics#1%
+%D {\Nopic[Topics]{#1}
+%D \placelist[Topic][criteriumcriterium=all]}
+%D \stoptyping
+%D
+%D but the next alternative sort of ignores this command when
+%D no list is found.
+
+\def\Topics#1%
+ {\determinelistcharacteristics[Topic]
+ \ifcase\utilitylistlength\else
+ \Nopic[Topics]{#1}
+ \placelist[Topic][criterium=all]
+ \fi}
+
+%D \macros
+%D {setuplist}
+%D
+%D We use the single item command to achieve a result similar
+%D to the itemizations.
+
+\setuplist
+ [Topic]
+ [alternative=command,
+ command=\TopicListCommand]
+
+\def\TopicListCommand#1#2#3%
+ {\item#2\par}
+
+%D A dummy command, needed to be compatible with the other
+%D presentation styles.
+
+\def\Subjects%
+ {}
+
+%D \macros
+%D {StartTitlePage}
+%D
+%D We use a nested \type {\everypar}; everything in there
+%D will be put in front of each paragraph. The nesting prevents
+%D the first paragraph from indenting. The struts give the
+%D lines a decent height, which looks better inrelation to the
+%D next pages.
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \bfd\setupinterlinespace
+ \everypar{\everypar{\advance\leftskip30pt\relax}}
+ \let\\=\blank
+ \begstrut}
+
+\def\StopTitlePage%
+ {\endstrut
+ \vfill
+ \stopstandardmakeup}
+
+%D \macros
+%D {TitlePage}
+%D
+%D The title page can be generated with one command:
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\usemodule[pre-antikwa]
+
+\starttext
+
+\TitlePage{Title Page\\pre-polish}
+
+\Topics{Some Nice Lists}
+
+\Topic{Some Lists}
+
+\Subject{A list}
+
+\startitemize
+\item first
+\item second
+\stopitemize
+
+\Subject{A bigger list}
+
+\startitemize
+\item first
+\item second
+\item third
+\item fourth
+\stopitemize
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-07.tex b/tex/context/modules/common/s-pre-07.tex
new file mode 100644
index 000000000..ba62b3236
--- /dev/null
+++ b/tex/context/modules/common/s-pre-07.tex
@@ -0,0 +1,212 @@
+%D \module
+%D [ file=s-pre-07,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 7,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style was made for the \NTS\ presentation at
+%D \EUROTEX\ 1999. It's a wink to programming in a webbed way.
+%D This is just one way of implementing such a style. Today
+%D we have more \METAPOST\ interfacing available, and
+%D thereby moore tools and alternative ways to reach such a
+%D goal. I must admit that the main macro looks fuzzy. On
+%D the other hand, the presentation can look quite structured.
+%D
+%D \starttyping
+%D \Topics{...}
+%D
+%D \StartIdeas
+%D \Topic{...}
+%D \StartIdea ... \StopIdea
+%D \StartIdea ... \StopIdea
+%D \StopIdeas
+%D \stoptyping
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+\usemodule
+ [abr-02]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupinteractionscreen
+ [option=max]
+
+%D In order to prevent loops due to random placement, we
+%D keep the random seed reasonable constant.
+
+\setupsystem
+ [random=big]
+
+\setupcolors
+ [state=start]
+
+\definecolor[gray] [s=.4]
+\definecolor[lightgray][s=.9]
+
+\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4]
+\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4]
+\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4]
+
+\definecolor[PageColor][gray]
+\definecolor[TextColor][lightgray]
+\definecolor[LineColor][yellow]
+
+\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan]
+\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta]
+\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow]
+
+\setupinteraction
+ [state=start,
+ display=new,
+ color=LineColor,
+ contrastcolor=LineColor]
+
+\startuseMPgraphic{shape}
+ path p ; color c, w ; numeric width, height ;
+ c := \MPcolor{LineColor} ; w := \MPcolor{TextColor} ;
+ width := \overlaywidth ; height := \overlayheight ;
+ pickup pencircle scaled .5cm ;
+ p := unitcircle
+ xscaled \MPw{\Idea} yscaled \MPh{\Idea}
+ shifted \MPxy{\Idea} ;
+ for z = (0,.5height), (width,.5height), (.5width,0), (.5width,height),
+ (0,0), (width,height), (0,height), (width,0) :
+ draw center p -- z withcolor c ;
+ endfor ;
+ fill p withcolor w ;
+ draw p withcolor c ;
+ p := unitcircle
+ xscaled \MPw{\Page} yscaled \MPh{\Page}
+ shifted \MPxy{\Page} ;
+ pickup pencircle scaled .25cm ;
+ fill p withcolor w ;
+ draw p withcolor c ;
+ draw unitsquare xscaled width yscaled height withcolor c ;
+\stopuseMPgraphic
+
+\defineoverlay [shape] [\useMPgraphic{shape}]
+\defineoverlay [nextpage] [\overlaybutton{nextpage}]
+\defineoverlay [previouspage] [\overlaybutton{previouspage}]
+\defineoverlay [content] [\overlaybutton{content}]
+\defineoverlay [forward] [\overlaybutton{forward}]
+
+\setupbackgrounds
+ [page]
+ [background={color,previouspage,shape},
+ backgroundcolor=PageColor]
+
+\def\StartIdea%
+ {\xdef\Idea{idea:\realfolio}
+ \xdef\Page{page:\realfolio}
+ \startstandardmakeup
+ \dontcomplain
+ \vbox to \makeupheight \bgroup
+ \getrandomdimen\scratchdimen{75pt}{600pt}\vskip 0pt plus \scratchdimen
+ \hbox to \makeupwidth \bgroup
+ \getrandomdimen\scratchdimen{75pt}{600pt}\hskip 0pt plus \scratchdimen
+ \hpos{idea:\realfolio} \bgroup
+ \framed
+ [width=.6\hsize,height=fit,offset=2cm,align=middle,
+ frame=off,strut=no,background=forward]
+ \bgroup
+ \setupwhitespace[big]}
+
+\def\StopIdea%
+ {\egroup
+ \egroup
+ \getrandomdimen\scratchdimen{75pt}{600pt}\hskip 0pt plus \scratchdimen
+ \egroup
+ \getrandomdimen\scratchdimen{75pt}{600pt}\vskip 0pt plus \scratchdimen
+ \egroup
+ \ifx\CurrentTopic\empty \else
+ \vskip-\makeupheight
+ \vbox to \makeupheight
+ {\vfill
+ \ifx\CurrentListTopic\empty\else
+ \writetolist[Topic]{}{\CurrentListTopic}
+ \fi
+ \hbox to \makeupwidth
+ {\hfill
+ \hpos{page:\realfolio}
+ {\framed
+ [offset=.5cm,frame=off,background=content]
+ {\bf\ignorespaces\CurrentTopic\unskip}}%
+ \hskip.5cm}
+ \vskip.5cm}
+ \fi
+ \stopstandardmakeup
+ \let\CurrentListTopic\empty}
+
+\definelist
+ [Topic]
+
+\setuplist
+ [Topic]
+ [alternative=f,
+ expansion=command]
+
+\let\CurrentTopic\empty
+\let\CurrentListTopic\empty
+
+\long\def\StartTopic#1\StopTopic
+ {\long\def\CurrentTopic{#1}
+ \let\CurrentListTopic\CurrentTopic}
+
+\def\Topic#1%
+ {\StartTopic#1\StopTopic}
+
+\def\Topics#1%
+ {\StartIdeas
+ \def\CurrentTopic{#1}
+ \StartIdea
+ \pagereference[content]
+ \placelist[Topic][criterium=all]
+ \StopIdea
+ \StopIdeas}
+
+\newcounter\CurrentIdeas
+
+\def\StartIdeas%
+ {\ifnum\CurrentIdeas=6 \doglobal\newcounter\CurrentIdeas \fi
+ \doglobal\increment\CurrentIdeas
+ \definecolor[LineColor][linecolor \CurrentIdeas]}
+
+\def\StopIdeas%
+ {}
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\Topics{This is about \unknown}
+
+\StartIdeas
+ \Topic{Some topic}
+ \StartIdea An idea \unknown \StopIdea
+ \StartIdea \unknown\ and another \StopIdea
+\StopIdeas
+
+\stoptext
+
+
diff --git a/tex/context/modules/common/s-pre-08.tex b/tex/context/modules/common/s-pre-08.tex
new file mode 100644
index 000000000..b545bef23
--- /dev/null
+++ b/tex/context/modules/common/s-pre-08.tex
@@ -0,0 +1,271 @@
+%D \module
+%D [ file=s-pre-08,
+%D version=1999.09.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 8,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is one of the 6 styles made for the \NTS\ presentation
+%D at \EUROTEX\ 1999. The idea was to demonstrate a couple of
+%D nasty things that one can do with \PDFTEX, being an example
+%D of an extension. Afterwards it was provded that this could
+%D also be done using traditional \TEX.
+%D
+%D This version is nearly the same as the original, although
+%D since then the \METAPOST\ related macro have become more
+%D smooth. The original used a couple of boxes, skipt and
+%D fills, while this version uses the layer mechanism that
+%D came available in fall 2000. This style is actually more a
+%D demonstration gimmick than a real useful one.
+
+%D You may want to turn on layer tracing:
+%D
+%D \starttyping
+%D \tracelayerstrue
+%D \stoptyping
+
+\setuppapersize
+ [S6][S6]
+
+\setupbodyfont
+ [pos,10pt]
+
+%D We use the whole page and have no margins.
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupcolors
+ [state=start]
+
+\definecolor[TextColor][s=.9]
+\definecolor[PageColor][r=.5,g=.4,b=.3]
+\definecolor[LineColor][r=.7,g=.6,b=.5]
+
+\definecolor[ColorPage][r=.5,g=.6,b=.7]
+\definecolor[ColorLine][r=.3,g=.4,b=.5]
+
+\setupinteraction
+ [state=start,
+ display=new]
+
+\setupinteractionscreen
+ [option=max]
+
+%D The page, sample text and pagenumber will have a background
+%D graphic.
+
+\defineoverlay [page] [\uniqueMPgraphic{page}]
+\defineoverlay [graphic] [\uniqueMPgraphic{graphic}]
+\defineoverlay [number] [\uniqueMPgraphic{number}]
+
+%D Each element will also be a button.
+
+\defineoverlay [nextpage] [\overlaybutton{nextpage}]
+\defineoverlay [previouspage] [\overlaybutton{previouspage}]
+\defineoverlay [forward] [\overlaybutton{forward}]
+
+%D We are going to put all three elements on a layer.
+
+\definelayer [main]
+\defineoverlay [main] [\composedlayer{main}]
+
+%D The page backgrounds are as follows:
+
+\setupbackgrounds
+ [page]
+ [background={previouspage,page}]
+
+%D We could have put the main layer on the page overlay, but
+%D the next solution makes us independent of the back and top
+%D margins. The \type {idea} layer is for user purposes.
+
+\setupbackgrounds
+ [text]
+ [background={main,idea}]
+
+%D The page number, sample text and explanation all have
+%D associated framed texts. The two overlays \type {sample}
+%D and \type {text} and there for special (user) purposes.
+
+\defineframedtext
+ [PageText]
+ [width=fit,offset=.5cm,
+ before=,after=,frame=off,background={number,forward}]
+
+\defineframedtext
+ [SampleText]
+ [width=.6\makeupwidth,height=fit,offset=2cm,align=middle,
+ before=,after=,frame=off,background={graphic,sample,nextpage}]
+
+\defineframedtext
+ [TextText]
+ [width=.6\makeupwidth,height=fit,offset=2cm,align=middle,
+ before=,after=,frame=off,background={text,nextpage}]
+
+%D Nothing goes on the page directly, since we use layers. The
+%D \type {\null} command makes sure that at least something is
+%D on the page so that the page is flushed. Here we also take
+%D care of placing the page number.
+
+\def\StartIdea
+ {\null \dontcomplain}
+
+\def\StopIdea
+ {\setlayer
+ [main]
+ [x=\makeupwidth,y=.5cm,hoffset=-.5cm,location=lb]
+ {\PageText{\pagenumber}}
+ \page}
+
+%D Both texts get their position registered.
+
+\def\StartSample
+ {\setlayer
+ [main]
+ [hoffset=.75cm,voffset=.75cm]
+ \bgroup \hpos {SampText:\realfolio} \bgroup \startSampleText [none]}
+
+\def\StopSample
+ {\stopSampleText \egroup \egroup}
+
+%D Here the position of the sample text and explanationary
+%D text are passed on to the graphic that concerns the latter.
+
+% use setlayertext instead
+
+\def\StartText
+ {\setMPpositiongraphic
+ {TextText:\realfolio}{text}{other=SampText:\realfolio}
+ \setlayer
+ [main]
+ [x=\makeupwidth,y=\makeupheight,
+ hoffset=-.75cm,voffset=-.75cm,
+ location=lt]
+ \bgroup \noindent \hpos {TextText:\realfolio} \bgroup \startTextText [none]}
+
+\def\StopText
+ {\stopTextText \egroup \egroup}
+
+%D The graphics that encircle the two texts are related to
+%D their position. This is because when they overlay, a shine
+%D through is shown. This only shows up when there is enough
+%D text to make them overlap.
+
+\startuniqueMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled .5cm ;
+ fill Page withcolor \MPcolor{PageColor} ;
+ draw Page withcolor \MPcolor{LineColor} ;
+ StopPage ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{number}
+ path p ; p := fullcircle xscaled OverlayWidth yscaled OverlayHeight;
+ pickup pencircle scaled .25cm ;
+ fill p withcolor \MPcolor{TextColor} ;
+ draw p withcolor (white-\MPcolor{PageColor}) ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{graphic}
+ path p ; p := fullcircle xscaled OverlayWidth yscaled OverlayHeight;
+ pickup pencircle scaled .5cm ;
+ fill p withcolor \MPcolor{TextColor} ;
+ draw p withcolor \MPcolor{LineColor} ;
+\stopuniqueMPgraphic
+
+%D This graphic is calculated when a position is flushed that
+%D has this graphics as attached. The \type {self} reference
+%D is provided by \CONTEXT\ itself.
+
+\startMPpositiongraphic{text}
+ initialize_box(\MPpos{\MPvar{other}}) ;
+ path p ; p := fullcircle xscaled wxy yscaled hxy shifted cxy ;
+ initialize_box(\MPpos{\MPvar{self}}) ;
+ path q ; q := fullcircle xscaled wxy yscaled hxy shifted cxy ;
+ pickup pencircle scaled .5cm ;
+ fill q withcolor \MPcolor{TextColor} ;
+ draw p withcolor (white-\MPcolor{PageColor}) ;
+ clip currentpicture to q ;
+ draw q withcolor \MPcolor{LineColor} ;
+ anchor_box(\MPanchor{\MPvar{self}}) ;
+\stopMPpositiongraphic
+
+%D In order to be complete, we also define a title page.
+%D Here suddenly the text background shows up.
+
+\def\StartTitlePage
+ {\startstandardmakeup
+ \dontcomplain
+ \setupframedtexts[TextText][width=fit]
+ \StartText
+ \bfd\setupinterlinespace
+ \def\\{\blank\bfc\setupinterlinespace\def\\{\blank}}}
+
+\def\StopTitlePage
+ {\StopText
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D For this purpose, we redefine the position graphic to
+%D handle a text only case:
+
+\startMPpositiongraphic{text}
+ if box_found(\MPpos{\MPvar{other}}) :
+ initialize_box(\MPpos{\MPvar{other}}) ;
+ path p ; p := fullcircle xscaled wxy yscaled hxy shifted cxy ;
+ fi ;
+ initialize_box(\MPpos{\MPvar{self}}) ;
+ path q ; q := fullcircle xscaled wxy yscaled hxy shifted cxy ;
+ pickup pencircle scaled .5cm ;
+ fill q withcolor \MPcolor{TextColor} ;
+ if box_found(\MPpos{\MPvar{other}}) :
+ draw p withcolor (white-\MPcolor{PageColor}) ;
+ clip currentpicture to q ;
+ draw q withcolor \MPcolor{LineColor} ;
+ else :
+ draw q withcolor (white-\MPcolor{PageColor}) ;
+ fi ;
+ anchor_box(\MPanchor{\MPvar{self}}) ;
+% setbounds currentpicture to boundingbox origin ;
+\stopMPpositiongraphic
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\TitlePage
+ {Fancy Styles:\\layers}
+
+\StartIdea
+ \StartSample
+ \input tufte
+ \StopSample
+ \StartText
+ \input reich
+ \StopText
+\StopIdea
+
+\StartIdea
+ \StartSample
+ \input knuth
+ \StopSample
+ \StartText
+ \input reich
+ \StopText
+\StopIdea
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-09.tex b/tex/context/modules/common/s-pre-09.tex
new file mode 100644
index 000000000..a20b9f31a
--- /dev/null
+++ b/tex/context/modules/common/s-pre-09.tex
@@ -0,0 +1,380 @@
+%D \module
+%D [ file=s-pre-09,
+%D version=unknown,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 9,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D I made this style when I had to give a presentation on
+%D the \MAPS\ bibliography production for several user group
+%D meetings. This style is rather tuned for combinations of
+%D examples and explanations. The colors match the \MAPS\
+%D bibliography colors.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+%D A couple of years later, in 2001 this style was documented
+%D and made public. While documenting, I also changed box
+%D building on top of overlays into the now available layer
+%D positioning. So, this styles demonstrates quite some
+%D tricks.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+%D Local environments can be set by using the setups commands.
+%D For downward compatibility, we keep supporting the \type
+%D {\...Settings} hooks. Using local environments is seldom
+%D needed.
+
+\let\TextSettings \empty
+\let\SampleSettings\empty
+
+\startsetups [text] \TextSettings \stopsetups
+\startsetups [sample] \SampleSettings \stopsetups
+
+%D The dimensions are kind of fixed.
+
+\def\FrameWidth {448pt}
+\def\FrameHeight {348pt}
+\def\FrameOffset {24pt}
+\def\FrameSkip {12pt}
+
+%D But they {\em can} and {\em will} be changed.
+
+\def\FrameWidth {408pt}
+\def\FrameHeight {318pt}
+
+%D The funny values come from the $3:4$ display aspect
+%D ratio.
+
+\setupcolors
+ [state=start]
+
+\definecolor[PageColor] [s=.40]
+\definecolor[TextColor] [s=.90]
+\definecolor[InteractionColor][r=.40]
+\definecolor[LineColor] [r=.60,g=.60]
+
+%D Of course we go interactive and since we will probably
+%D open other documents, we make sure that the viewer opens a
+%D new window.
+
+\setupinteraction
+ [color=InteractionColor,
+ contrastcolor=LineColor,
+ display=new,
+ state=start]
+
+\setupinteractionscreen
+ [option=max]
+
+%D Before we come to the real macros, we do a little bit of
+%D tuning.
+
+\setupitemize
+ [1][packed]
+
+\setuptyping
+ [blank=medium]
+
+%D Apart from the titlepage, the page gets a simple colored
+%D background. Later we will activate the background.
+
+\setupbackgrounds
+ [page]
+ [backgroundcolor=PageColor]
+
+%D Everything gets frames by a nice \METAPOST\ frame.
+
+\defineoverlay [background] [\uniqueMPgraphic{background}]
+
+\startuniqueMPgraphic{background}
+ path p ; color c, w, d ;
+ c := \MPcolor{PageColor} ;
+ w := \MPcolor{TextColor} ;
+ d := \MPcolor{LineColor} ;
+ p := unitsquare xscaled OverlayWidth yscaled OverlayHeight ;
+ pickup pencircle scaled (1.5*\FrameSkip) ;
+ draw p withcolor c ;
+ pickup pencircle scaled \FrameSkip ;
+ fill p withcolor w ;
+ draw p withcolor d ;
+\stopuniqueMPgraphic
+
+%D We will present samples and explanation pair||wise, so
+%D we need a hyperlink that skips a page.
+
+\defineoverlay [nextpage] [\overlaybutton{nextpage}]
+\defineoverlay [previouspage] [\overlaybutton{previouspage}]
+\defineoverlay [skippage] [\overlaybutton{page(+2)}]
+
+%D Layers are normally used to position multiple content on
+%D a specific overlay. Here we will use them to position
+%D only and since the samples and text will swap place, we
+%D will use quite a few layers.
+
+\defineoverlay [text] [\composedlayer{text}]
+\defineoverlay [sample] [\composedlayer{sample}]
+\defineoverlay [common] [\composedlayer{common}]
+
+%D There are three positions. When combined, the sample and
+%D text windows overlap, otherwise the lone window is
+%D centered. We could have used one layer and reversed the
+%D order by setting the \type {direction} parameter, but
+%D this approach is more readable.
+
+\definelayer
+ [text]
+ [x=\makeupwidth,y=\makeupheight,location=lt,
+ hoffset=-\FrameSkip,voffset=-\FrameSkip]
+
+\definelayer
+ [sample]
+ [hoffset=\FrameSkip,voffset=\FrameSkip]
+
+\definelayer
+ [common]
+ [x=.5\makeupwidth,y=.5\makeupheight,location=c]
+
+%D The topic is put in the lower right corner of the text
+%D window.
+
+\defineoverlay [topic] [\composedlayer{topic}]
+
+\definelayer
+ [topic]
+ [x=\FrameWidth,y=\FrameHeight,location=lt,
+ hoffset=-\FrameOffset,voffset=-\FrameSkip]
+
+%D The topic is put in a framed box. That way we can make
+%D sure that it gets a background, which looks better when
+%D it covers something else. Otherwise we could have stuct
+%D to:
+%D
+%D \starttyping
+%D \def\Topic#1%
+%D {\setlayer[topic]{\color[PageColor]{\bfb\setstrut#1}}}
+%D \stoptyping
+%D
+%D But, we go for the nice alternative:
+
+\def\Topic#1%
+ {\doifsomething{#1}
+ {\setlayer [topic]
+ {\bfb\setstrut
+ \inframed
+ [frame=off,foregroundcolor=PageColor,offset=0pt,
+ background=color,backgroundcolor=TextColor]
+ {#1}}}}
+
+%D The sample as well as the explanation will be collected in
+%D a buffer. That way we can reuse the content. We could
+%D have used a box instead, but can we be sure that the content
+%D is not adapting itself? So, buffers we use.
+
+\resetbuffer[sample]
+\resetbuffer[text]
+
+%D Both the sample and explanation are kind of windowed.
+
+\defineframedtext
+ [SampleText]
+ [width=\FrameWidth,height=\FrameHeight,offset=\FrameOffset,
+ frame=off,align=normal,strut=no,before=,after=,
+ background={background,nextpage}]
+
+%D We safe some keying in by combining things in one macro.
+
+\def\DoSampleText#1#2#3% kind layer overlays
+ {\setupframedtexts[SampleText][background={background,#3}]
+ \setlayer[#2]
+ {\startSampleText[none]
+ \setups[#1]
+ \getbuffer[#1]
+ \stopSampleText}}
+
+\def\StartSample{\dostartbuffer[sample][StartSample][StopSample]}
+\def\StartText {\dostartbuffer[text] [StartText] [StopText]}
+
+%D The following definitions apply at the outer level.
+
+\def\StopSample
+ {\startstandardmakeup
+ \DoSampleText{sample}{common}{nextpage}
+ \stopstandardmakeup
+ \resetbuffer[sample]}
+
+\def\StopText
+ {\startstandardmakeup
+ \DoSampleText{text}{common}{topic,nextpage}
+ \stopstandardmakeup
+ \resetbuffer[text]}
+
+\setupbackgrounds[page][background={color,nextpage}]
+\setupbackgrounds[text][background=common]
+
+%D When we combine sample and text, we get slightly
+%D different definitions. As you can see we generate two
+%D pages. Watch how we manipulate the order of the
+%D overlays and teh nature of the buttons. Here data
+%D abstraction really pays off.
+
+\def\StartIdea
+ {\bgroup
+ \let\StopSample\relax
+ \let\StopText \relax}
+
+\def\StopIdea%
+ {\setupbackgrounds[page][background={color,skippage}]
+ \setupbackgrounds[text][background={text,sample}]
+ \startstandardmakeup
+ \DoSampleText{sample}{sample}{previouspage}
+ \DoSampleText{text} {text} {topic,nextpage}
+ \stopstandardmakeup
+ \setupbackgrounds[page][background={color,nextpage}]
+ \setupbackgrounds[text][background={sample,text}]
+ \startstandardmakeup
+ \DoSampleText{sample}{sample}{previouspage}
+ \DoSampleText{text} {text} {topic,nextpage}
+ \stopstandardmakeup
+ \egroup}
+
+%D The rest of the definitions takes care of the title page.
+%D Please don't steal this one for your own documents.
+
+\defineoverlay[joke] [\useMPgraphic{joke}{n=0}] % not to be changed!
+
+\startuseMPgraphic{joke}{n}
+ StartPage ;
+ path p, q ; numeric w ; pair xy ;
+ set_grid(OverlayWidth,OverlayHeight,OverlayWidth/8,OverlayHeight/8) ;
+ if \MPvar{n}=1 :
+ p := fulldiamond ; fill Page withcolor \MPcolor{TextColor} ;
+ else :
+ p := fullsquare ; fill Page withcolor \MPcolor{PageColor} ;
+ fi ;
+ forever :
+ xy := center Page randomized (OverlayWidth,OverlayHeight) ;
+ if new_on_grid(xpart xy, ypart xy) :
+ q := (p xyscaled (OverlayWidth/5,OverlayHeight/5))
+ randomized (\FrameSkip,\FrameSkip)
+ shifted xy ;
+ w := (\FrameSkip) randomized (\FrameSkip/2) ;
+ draw q withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ;
+ fill q withcolor \MPcolor{TextColor} ;
+ draw q withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+ StopPage ;
+\stopuseMPgraphic
+
+\defineoverlay[fuzzy][\useMPgraphic{fuzzy}]
+
+\startuseMPgraphic{fuzzy}
+ path p ; numeric w ;
+ p := (fullsquare xyscaled (OverlayWidth,OverlayHeight))
+ randomized (\FrameSkip,\FrameSkip) ;
+ w := (\FrameSkip) randomized (\FrameSkip/2) ;
+ draw p withcolor \MPcolor{PageColor} withpen pencircle scaled (1.5w) ;
+ fill p withcolor \MPcolor{TextColor} ;
+ draw p withcolor \MPcolor{LineColor} withpen pencircle scaled ( w) ;
+\stopuseMPgraphic
+
+%D This time we use a fit window, but with a slightly randomized
+%D frame, our trademark so to say.
+
+\def\StartTitlePage
+ {\bgroup
+ \setupbackgrounds[page][background={joke,nextpage}]
+ \startstandardmakeup
+ \switchtobodyfont[big]
+ \setupframedtexts
+ [SampleText]
+ [background=fuzzy,
+ foregroundcolor=PageColor,
+ width=fit,
+ height=fit,
+ align=middle]
+ \startSampleText[middle]
+ \bfd\setupinterlinespace
+ \def\\{\bfb\setupinterlinespace\vfil\def\\{\vfil}}}
+
+\def\StopTitlePage
+ {\stopSampleText
+ \stopstandardmakeup
+ \egroup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D Let's nill some error prone presentation macros.
+
+\let\Subject \Topic
+\let\Topics \gobbleoneargument
+\let\Subjects \relax
+
+%D We will avoid \quote {overfull} messages.
+
+\dontcomplain
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\setupbodyfont[12pt]
+
+\TitlePage{Quotes, Quotes\\and more quotes}
+
+\StartIdea
+ \StartSample
+ \input knuth \par
+ \StopSample
+ \StartText
+ \Topic{Tufte}
+ \input tufte \par
+ \StopText
+ \StopIdea
+
+\StartIdea
+ \StartSample
+ \input materie \par
+ \StopSample
+ \StartText
+ \input reich \par
+ \StopText
+\StopIdea
+
+\StartText
+ \input tufte \par
+\StopText
+
+\StartIdea
+ \StartSample
+ \input knuth \par
+ \StopSample
+ \StartText
+ \input tufte \par
+ \StopText
+\StopIdea
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-10.tex b/tex/context/modules/common/s-pre-10.tex
new file mode 100644
index 000000000..a92e5af01
--- /dev/null
+++ b/tex/context/modules/common/s-pre-10.tex
@@ -0,0 +1,308 @@
+%D \module
+%D [ file=s-pre-10,
+%D version=unknown,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 10,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style is derived from the ninth style, which was
+%D used first at \EUROTEX\ 99 and later at \TUG\ 2000. This
+%D alternative build up a page.
+
+\startmode [demo]
+ \disablemode[demo] \usemodule[pre-09] \enablemode[demo]
+\stopmode
+
+\startnotmode [demo]
+ \usemodule[pre-09]
+\stopnotmode
+
+%D We use blue colors instead of yellow ones. Since we have
+%D used symbolic names, we can easily overload the existing
+%D scheme.
+
+\definecolor[LineColor][r=.40,g=.40,b=1.00]
+
+%D Here we don't use fixed dimensions, but fit the sample
+%D windows and derive the text windows's width from this one.
+
+\setupframedtexts
+ [SampleText]
+ [width=fit,height=fit,
+ background={background,nextpage}]
+
+%D The topic goes to the top right corner of the screen which
+%D means that it is positioned left down to the reference
+%D point. Watch how we make data on this layer (here only
+%D the topic but it can be more) persistent.
+
+\setuplayer
+ [topic]
+ [y=0pt,x=\makeupwidth,location=lb,state=repeat,
+ hoffset=-\FrameSkip,voffset=\FrameSkip]
+
+%D Clicking on the page brings us back.
+
+\setupbackgrounds
+ [page]
+ [background={previouspage,color,topic}]
+
+%D All layers end up on the text area. This could have been
+%D the page area too since these have the same dimensions.
+
+\setupbackgrounds
+ [text]
+ [background={common,sample,text}]
+
+%D Because we build up the text window step by step, we will
+%D separate the entries by white space.
+
+\startsetups [always]
+ \setupwhitespace[big]
+ \setupblank[big]
+\stopsetups
+
+%D The \type {\Topic} commands can be simplified to:
+
+\def\Topic#1%
+ {\resetlayer[topic]
+ \setlayer[topic]{\bfb\setstrut\color[TextColor]{#1}}}
+
+%D We also provide a way to erase the topic.
+
+\def\NoTopic
+ {\resetlayer[topic]}
+
+%D We have to redefine the structuring commands to support
+%D the resetting of buffer counters.
+
+\newcounter\TextN
+
+\def\StartSample
+ {\doglobal\newcounter\TextN
+ \dostartbuffer[sample][StartSample][StopSample]}
+
+\def\StartText
+ {\doglobal\newcounter\TextN
+ \dostartbuffer[text][StartText][StopText]}
+
+\def\StartSubText
+ {\doglobal\increment\TextN
+ \dostartbuffer[text-\TextN][StartSubText][StopSubText]}
+
+\def\StopText
+ {\startstandardmakeup
+ \DoSampleText{text}{common}{nextpage}
+ \stopstandardmakeup}
+
+\def\StopSubText
+ {\startstandardmakeup
+ \DoSampleText{text}{common}{nextpage}
+ \stopstandardmakeup}
+
+%D The \type {\DoSampleText} command is adapted to support
+%D addition of subtexts (each subtext goes into its own
+%D buffer).
+
+\def\DoSampleText#1#2#3%
+ {\setupframedtexts[SampleText][background={background,#3}]
+ \bgroup
+ \setups[#1]%
+ \setups[always]%
+ \setbox\nextbox=\hbox
+ {\startSampleText[none]
+ \getbuffer[#1]\par
+ \doif{#1}{text}
+ {\dorecurse{\TextN}{\getbuffer[text-\recurselevel]\par}}
+ \stopSampleText}
+ \xdef\SampleTextWidth{\the\wd\nextbox}
+ \setlayer[#2]{\box\nextbox}%
+ \egroup}
+
+%D Since we are no longer swapping windows, we end up with a
+%D much simplier \type {\Stopidea} macro. We don't reset
+%D samples at the inner level.
+
+\def\StartIdea%
+ {\bgroup
+ \let\StopSample \relax
+ \let\StopText \relax
+ \let\StopSubText\relax
+ \def\StartSample{\dostartbuffer[sample][StartSample][StopSample]}}
+
+\def\StopIdea%
+ {\startstandardmakeup
+ \DoSampleText{sample}{sample}{nextpage}
+ \SetTextWidth
+ \DoSampleText{text} {text} {nextpage}
+ \stopstandardmakeup
+ \egroup}
+
+%D Here we determine the width of the text window. It is
+%D derived from the width of the sample and stays the same
+%D within a sequence.
+
+\def\SetTextWidth
+ {\ifnum\TextN<1 % yes or no, may change
+ \scratchdimen=\makeupwidth
+ \advance\scratchdimen by -\SampleTextWidth
+ \advance\scratchdimen by \FrameSkip
+ \xdef\SampleWidth{\the\scratchdimen}%
+ \fi
+ \setupframedtexts
+ [SampleText]
+ [width=\SampleWidth]}
+
+%D We use the (already implemented) second alternative of
+%D the titlepage graphic. Please don't change this.
+
+\defineoverlay[joke] [\useMPgraphic{joke}{n=1}] % not to be changed !
+
+\doifnotmode{demo}{\endinput}
+
+%D The demo section. The original presentation uses proper
+%D graphics and has better spacing.
+
+\def\SomeSymbol#1#2{\definedfont[ContextNavigation at #1]\char#2}
+
+\setupcombinations[distance=\FrameOffset,inbetween=\vskip\FrameOffset]
+
+\starttext
+
+\TitlePage{Some Famous Symbols}
+
+\Topic{Symbols}
+
+\StartSample
+ \startcombination[2*2]
+ {\SomeSymbol{5cm}{1}} {}
+ {\SomeSymbol{5cm}{3}} {}
+ {\SomeSymbol{5cm}{2}} {}
+ {\SomeSymbol{5cm}{4}} {}
+ \stopcombination
+\StopSample
+
+\Topic{Previous}
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{7cm}{1}
+ \StopSample
+ \StartText
+ This symbol can be used to indicate a hyperlink to a
+ previous page.
+ \StopText
+\StopIdea
+
+\StartIdea
+ \StartSubText
+ As one can expect there is also a symbol for going to
+ the next page.
+ \StopSubText
+\StopIdea
+
+\Topic{Previous}
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{9cm}{2}
+ \StopSample
+ \StartText
+ This symbol is actually just a mirrored version of the
+ first symbol we showed.
+ \StopText
+\StopIdea
+
+\NoTopic
+
+\StartText
+ Is this nice or not?
+\StopText
+
+\Topic{First and Last}
+
+\StartSample
+ \SomeSymbol{11cm}{3}
+\StopSample
+
+\StartSample
+ \SomeSymbol{11cm}{4}
+\StopSample
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{5cm}{3}
+ \StopSample
+ \StartText
+ A few screens back, we saw this symbol.
+ \StopText
+\StopIdea
+
+\StartIdea
+ \StartSubText
+ This symbol represents the beginning of something.
+ \StopSubText
+\StopIdea
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{5cm}{4}
+ \StopSample
+ \StartSubText
+ Just like this one represents an end.
+ \StopSubText
+\StopIdea
+
+\StartIdea
+ \StartSubText
+ They look just like the symbols found on audio and
+ video players.
+ \StopSubText
+\StopIdea
+
+\Topic{Summary}
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{6cm}{1}
+ \StopSample
+ \StartText
+ So we have a symbol for previous \unknown
+ \StopText
+\StopIdea
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{6cm}{2}
+ \StopSample
+ \StartSubText
+ \unknown\ and one for next \unknown
+ \StopSubText
+\StopIdea
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{6cm}{3}
+ \StopSample
+ \StartSubText
+ \unknown\ and yet another for first \unknown
+ \StopSubText
+\StopIdea
+
+\StartIdea
+ \StartSample
+ \SomeSymbol{6cm}{4}
+ \StopSample
+ \StartSubText
+ \unknown\ and of course for last.
+ \StopSubText
+\StopIdea
+
+\stoptext
+
diff --git a/tex/context/modules/common/s-pre-11.tex b/tex/context/modules/common/s-pre-11.tex
new file mode 100644
index 000000000..551c5ebbc
--- /dev/null
+++ b/tex/context/modules/common/s-pre-11.tex
@@ -0,0 +1,220 @@
+%D \module
+%D [ file=s-pre-11,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 11,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupbodyfont
+ [14.4pt,lbr]
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [click=no,
+ display=new,
+ state=start]
+
+\setupinteractionscreen
+ [option=max]
+
+\def\SomeShape%
+ {\resetMPdrawing
+ \startMPdrawing
+ path p[], q[] ; pair a, b ;
+ StartPage ;
+ \stopMPdrawing
+ \dorecurse{\CurrentTopic}
+ {\startMPdrawing
+ initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ;
+ p[\recurselevel] := tensecircle (wxy,hxy,.25cm) shifted cxy ;
+ fill p[\recurselevel] withcolor .9white ;
+ pickup pencircle scaled .25cm ;
+ \ifnum\recurselevel=\CurrentTopic\space
+ draw p[\recurselevel] withcolor \MPcolor{ShowColor} ;
+ \else
+ draw p[\recurselevel] withcolor \MPcolor{DoneColor} ;
+ \fi
+ \stopMPdrawing}%
+ \dorecurse{\CurrentMaxItem}
+ {\startMPdrawing
+ initialize_box(\MPpos{item-\realfolio-\recurselevel}) ;
+ linewidth := .25cm ;
+ q[\recurselevel] := tensecircle (wxy,hxy,linewidth) shifted cxy ;
+ fill q[\recurselevel] withcolor .9white ;
+ pickup pencircle scaled linewidth ;
+ \ifnum\recurselevel=\CurrentMaxItem\space
+ draw q[\recurselevel] withcolor \MPcolor{ShowColor} ;
+ \else
+ draw q[\recurselevel] withcolor \MPcolor{DoneColor} ;
+ \fi
+ \stopMPdrawing}%
+ \dostepwiserecurse{2}{\CurrentTopic}{1}
+ {\startMPdrawing
+ draw
+ rt point 3 of p[\recurselevel-1] --
+ lft point 7 of p[\recurselevel]
+ withcolor \MPcolor{ArrowColor} ;
+ \stopMPdrawing}%
+ \dostepwiserecurse{2}{\CurrentMaxItem}{1}
+ {\startMPdrawing
+ draw
+ bot point 9 of q[\recurselevel-1] --
+ top point 5 of q[\recurselevel]
+ withcolor \MPcolor{ArrowColor} ;
+ \stopMPdrawing}%
+ \startMPdrawing
+ draw Page
+ withpen pencircle scaled .5cm
+ withcolor \MPcolor{EdgeColor} ;
+ StopPage ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \getMPdrawing}
+
+\def\TitlePage#1%
+ {\startstandardmakeup
+ \setupalign[middle]
+ \def\\{\vfil\bfb\setupinterlinespace}
+ \bfd\setupinterlinespace
+ \vfil#1\vfil\vfil
+ \stopstandardmakeup}
+
+\definecolor[PageColor][r=.5,g=.4,b=.3]
+\definecolor[LineColor][r=.7,g=.6,b=.5]
+
+\definecolor[PageColor] [s=.60]
+\definecolor[ShowColor] [r=.40]
+\definecolor[EdgeColor] [g=.40]
+\definecolor[DoneColor] [r=.40,g=.40]
+\definecolor[ArrowColor] [b=.40]
+\definecolor[LineColor] [r=.60,g=.60]
+\definecolor[GotoColor] [ArrowColor]
+
+\setupinteraction[color=GotoColor,contrastcolor=GotoColor]
+
+\defineoverlay [shape] [\SomeShape]
+\defineoverlay [next] [\overlaybutton{forward}] % [{nextpage}]
+
+\setupbackgrounds
+ [page]
+ [background={color,next,shape},
+ backgroundcolor=PageColor]
+
+\doglobal\newcounter\CurrentMaxItem
+\doglobal\newcounter\CurrentItem
+\doglobal\newcounter\CurrentTopic
+
+\def\StartIdea%
+ {\doglobal\newcounter\CurrentItem}
+
+\def\StartTopic%
+ {\doglobal\increment\CurrentTopic
+ \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]}
+
+\def\StopIdea%
+ {\dorecurse{\CurrentItem}
+ {\let\CurrentMaxItem\recurselevel
+ \doStopIdea}}
+
+\def\doStopIdea%
+ {\startstandardmakeup
+ \dontcomplain
+ \vskip.875cm
+ \hbox to \makeupwidth
+ {\hfill
+ \dorecurse{\CurrentTopic}
+ {\edef\Topic{topic-\realfolio-\recurselevel}%
+ \hpos
+ {\Topic}
+ {\framed
+ [frame=off,align=middle,offset=.25cm]
+ {\getbuffer[topic-\recurselevel]}}%
+ \ifnum\recurselevel<\CurrentTopic
+ \hskip.875cm
+ \fi}%
+ \hfill}
+ \vskip.875cm
+ \vfilll
+ \dorecurse{\CurrentMaxItem}
+ {\edef\Item{item-\realfolio-\recurselevel}
+ \hbox to \makeupwidth
+ {\hfill
+ \hpos
+ {\Item}
+ {\framed
+ [width=.75\makeupwidth,
+ frame=off,
+ align=middle,offset=.125cm]
+ {\getbuffer[item-\recurselevel]}}%
+ \hfill}
+ \vskip.875cm}
+ \vfilll
+ \stopstandardmakeup}
+
+\def\StartItem%
+ {\doglobal\increment\CurrentItem
+ \dostartbuffer[item-\CurrentItem][StartItem][StopItem]}
+
+\lefthyphenmin =\maxdimen
+\righthyphenmin=\maxdimen
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\StartIdea
+ \StartTopic
+ A Nice Idea
+ \StopTopic
+ \StartItem
+ \input reich \relax
+ \StopItem
+ \StartItem
+ \input reich \relax
+ \StopItem
+ \StartItem
+ \input reich \relax
+ \StopItem
+\StopIdea
+
+\StartIdea
+ \StartTopic
+ One More Nice Idea
+ \StopTopic
+ \StartItem
+ \input reich \relax
+ \StopItem
+ \StartItem
+ \input reich \relax
+ \StopItem
+\StopIdea
+
+\StartIdea
+ \StartTopic
+ The Last Idea
+ \StopTopic
+ \StartItem
+ \input tufte \relax
+ \StopItem
+\StopIdea
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-12.tex b/tex/context/modules/common/s-pre-12.tex
new file mode 100644
index 000000000..23418fbba
--- /dev/null
+++ b/tex/context/modules/common/s-pre-12.tex
@@ -0,0 +1,226 @@
+%D \module
+%D [ file=s-pre-12,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 12,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupbodyfont
+ [14.4pt,lbr]
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [click=no,
+ display=new,
+ state=start]
+
+\setupinteractionscreen
+ [option=max]
+
+\def\SomeShape%
+ {\resetMPdrawing
+ \startMPdrawing
+ path p ; pair a, b ;
+ ahlength := .375cm ;
+ StartPage ;
+ draw Page %unitsquare
+ %xscaled PaperWidth yscaled PaperHeight
+ withpen pencircle scaled .5cm
+ withcolor \MPcolor{EdgeColor} ;
+ \stopMPdrawing
+ \dorecurse{\CurrentTopic}
+ {\startMPdrawing
+ initialize_box(\MPpos{topic-\realfolio-\recurselevel}) ;
+ p := tensecircle (wxy,hxy,.25cm) shifted cxy ;
+ fill p withcolor .9white ;
+ pickup pencircle scaled .25cm ;
+ \ifnum\recurselevel=\CurrentTopic
+ draw p withcolor \MPcolor{ShowColor} ;
+ a := bot point 7 of p ;
+ \else
+ draw p withcolor \MPcolor{DoneColor} ;
+ \fi
+ \stopMPdrawing}
+ \dorecurse{\CurrentMaxItem}
+ {\startMPdrawing
+ initialize_box(\MPpos{item-\realfolio-\recurselevel}) ;
+ linewidth := .25cm ;
+ p := tensecircle (wxy,hxy,linewidth) shifted cxy ;
+ fill p withcolor .9white ;
+ pickup pencircle scaled linewidth ;
+ b := rt point 3 of p ;
+ \ifnum\recurselevel=\CurrentMaxItem
+ draw p withcolor \MPcolor{ShowColor} ;
+ \else
+ draw p withcolor \MPcolor{DoneColor} ;
+ \fi
+ dxab := xpart a-xpart b ;
+ dyab := ypart a-ypart b ;
+ sign := if dyab>0 : - fi 1 ;
+ drawarrow
+ a --
+ a shifted (+2linewidth-dxab/2,0) {left} ..
+ if abs(dyab)>4linewidth :
+ a shifted (-dxab/2,+sign*2linewidth) --
+ b shifted (+dxab/2,-sign*2linewidth) ..
+ fi
+ {left} b shifted (-2linewidth+dxab/2,0) --
+ b
+ withcolor \MPcolor{ArrowColor} ;
+ \stopMPdrawing}%
+ \startMPdrawing
+ StopPage ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \getMPdrawing}
+
+\definecolor[PageColor][r=.5,g=.4,b=.3]
+\definecolor[LineColor][r=.7,g=.6,b=.5]
+
+\definecolor[PageColor] [s=.60]
+\definecolor[ShowColor] [r=.40]
+\definecolor[EdgeColor] [g=.40]
+\definecolor[DoneColor] [r=.40,g=.40]
+\definecolor[ArrowColor] [b=.40]
+\definecolor[LineColor] [r=.60,g=.60]
+\definecolor[GotoColor] [ArrowColor]
+
+\setupinteraction[color=GotoColor,contrastcolor=GotoColor]
+
+\defineoverlay [shape] [\SomeShape]
+\defineoverlay [next] [\overlaybutton{forward}]
+
+\setupbackgrounds
+ [page]
+ [background={color,next,shape},
+ backgroundcolor=PageColor]
+
+\doglobal\newcounter\CurrentItem
+\doglobal\newcounter\CurrentTopic
+\doglobal\newcounter\CurrentMaxItem
+
+\def\StartIdea%
+ {\doglobal\newcounter\CurrentItem}
+
+\def\StartTopic%
+ {\doglobal\increment\CurrentTopic
+ \dostartbuffer[topic-\CurrentTopic][StartTopic][StopTopic]}
+
+\def\StopIdea%
+ {\dorecurse{\CurrentItem}
+ {\let\CurrentMaxItem\recurselevel
+ \doStopIdea}}
+
+\def\IdeaWidth {.6\makeupwidth} % .5
+\def\TopicWidth{.2\makeupwidth} % .3
+
+\def\doStopIdea%
+ {\startstandardmakeup
+ \dontcomplain
+ \vbox to \makeupheight
+ {\vskip.75cm \relax % \vfill
+ \dorecurse{\CurrentMaxItem}
+ {\edef\Item{item-\realfolio-\recurselevel}
+ \hbox to \makeupwidth
+ {\hskip.75cm
+ \hpos
+ {\Item}
+ {\framed
+ [width=\IdeaWidth,frame=off,
+ align=middle,offset=.125cm]
+ {\getbuffer[item-\recurselevel]}}}
+ \vskip.875cm}
+ \vfill}
+ \vskip-\makeupheight
+ \vbox to \makeupheight
+ {\vskip.75cm \relax
+ \dorecurse{\CurrentTopic}
+ {\edef\Topic{topic-\realfolio-\recurselevel}
+ \hbox to \makeupwidth
+ {\hfill
+ \hpos
+ {\Topic}
+ {\framed
+ [width=\TopicWidth,frame=off,
+ align=middle,offset=.25cm]
+ {\getbuffer[topic-\recurselevel]}}%
+ \hskip.75cm}
+ \vskip.875cm}
+ \vfill}
+ \stopstandardmakeup}
+
+\def\StartItem%
+ {\doglobal\increment\CurrentItem
+ \dostartbuffer[item-\CurrentItem][StartItem][StopItem]}
+
+\lefthyphenmin =\maxdimen
+\righthyphenmin=\maxdimen
+
+\def\TitlePage#1%
+ {\startstandardmakeup
+ \setupalign[middle]
+ \def\\{\vfil\bfb\setupinterlinespace}
+ \bfd\setupinterlinespace
+ \vfil#1\vfil\vfil
+ \stopstandardmakeup}
+
+\endinput
+
+% \starttext
+%
+% \StartIdea
+% \StartTopic
+% What a topic
+% \StopTopic
+% \StartItem
+% \input reich \relax
+% \StopItem
+% \StartItem
+% \input reich \relax
+% \StopItem
+% \StartItem
+% \input reich \relax
+% \StopItem
+% \StopIdea
+%
+% \StartIdea
+% \StartTopic
+% One More Nice Idea
+% \StopTopic
+% \StartItem
+% \input reich \relax
+% \StopItem
+% \StartItem
+% \input reich \relax
+% \StopItem
+% \StopIdea
+%
+% \StartIdea
+% \StartTopic
+% The Last Idea
+% \StopTopic
+% \StartItem
+% \input tufte \relax
+% \StopItem
+% \StopIdea
+%
+% \stoptext
diff --git a/tex/context/modules/common/s-pre-13.tex b/tex/context/modules/common/s-pre-13.tex
new file mode 100644
index 000000000..7b4daa4b3
--- /dev/null
+++ b/tex/context/modules/common/s-pre-13.tex
@@ -0,0 +1,302 @@
+%D \module
+%D [ file=s-pre-13,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 13,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is again one of the \EUROTEX\ 99 styles. It's one of
+%D the quick and dirty styles supporting basic structuring.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt,
+ bottomdistance=.5cm,
+ bottom=1cm,
+ topspace=2cm,
+ backspace=2cm]
+
+%D This style is meant to be used with lucida handwriting
+%D fonts. If you don't have that font, you may reconsider
+%D using this style.
+
+\startmode[asintended] \setupbodyfont[lbr,hw] \stopmode
+
+%D These colors will mostly be used in the graphics drawn by
+%D \METAPOST.
+
+\setupcolors
+ [state=start]
+
+\definecolor[PageColor] [s=.6]
+\definecolor[TextColor] [s=.8]
+\definecolor[LineColor] [g=.4]
+\definecolor[SymbolColor][r=.4]
+
+%D When interacting, we will use button shaped that are
+%D quite random and thereby regenerated for each instance.
+
+\setupinteractionscreen
+ [option=max]
+
+\setupinteractionmenu
+ [bottom]
+ [state=start,
+ height=1cm,
+ middle=\hskip1cm]
+
+\setupinteraction
+ [state=start,
+ menu=on,
+ display=new,
+ click=no,
+ color=SymbolColor,
+ contrastcolor=SymbolColor]
+
+\startinteractionmenu[bottom]
+ \hfill
+ \got [previouspage] \symbol[prevmark] \\
+ \got [nextpage] \symbol[nextmark] \\
+ \got [CloseDocument] \symbol[stopmark] \\
+ \txt \tfd \SymbolColor \pagenumber \\
+\stopinteractionmenu
+
+%D When not processed at runtime, the itemmark graphics can
+%D result in processing loops due to funny dimensions.
+%D Therefore, from now on, the itemize macros limit the height
+%D and depth.
+
+\definesymbol[itemmark][\useMPgraphic{itemmark}]
+\definesymbol[stopmark][\useMPgraphic{stopmark}]
+\definesymbol[nextmark][\useMPgraphic{nextmark}]
+\definesymbol[prevmark][\useMPgraphic{prevmark}]
+
+%D Of course we have some backgrounds.
+
+\defineoverlay [page] [\useMPgraphic{page}]
+\defineoverlay [next] [\overlaybutton{forward}]
+\defineoverlay [prev] [\overlaybutton{PreviousJump}]
+
+\setupbackgrounds
+ [page]
+ [background={page,prev}]
+
+\setupbackgrounds
+ [text]
+ [background=next]
+
+\setuphead
+ [chapter]
+ [alternative=middle,
+ number=no,
+ color=SymbolColor,
+ style=\tfc]
+
+%D A little bit of tweaking.
+
+\setupwhitespace
+ [big]
+
+\setupitemize
+ [1]
+ [symbol=itemmark,
+ width=3\bodyfontsize]
+
+\def\StartTitlePage%
+ {\setupinteractionmenu[bottom][state=stop] % will be named page block
+ \startstandardmakeup
+ \setupalign[middle]
+ \def\\%
+ {\stopcolor
+ \vfil
+ \bfb\setupinterlinespace
+ \startcolor[black]}
+ \bfd\setupinterlinespace
+ \vfil
+ \startcolor[SymbolColor]}
+
+\def\StopTitlePage
+ {\stopcolor
+ \vfil\vfil
+ \stopstandardmakeup
+ \setupinteractionmenu[bottom][state=start]}
+
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\definehead[Topic][chapter]
+\definehead[Nopic][title]
+
+\setuplist
+ [Topic]
+ [criterium=all,
+ alternative=g,
+ interaction=all,
+ after=\blank]
+
+\def\Topics#1%
+ {\Nopic{#1}
+ \bgroup
+ \setupinteraction
+ [color=,
+ contrastcolor=]
+ \determinelistcharacteristics[Topic]
+ \ifnum\utilitylistlength>12
+ \startcolumns[n=2]
+ \placelist[Topic]
+ \stopcolumns
+ \else
+ \placelist[Topic]
+ \fi
+ \egroup}
+
+%D We don't support another level of structuring.
+
+\let\Subject \Topic
+\let\Subjects\relax
+
+%D Most of this style is \METAPOST\ definitions. We could
+%D have shared some code, but it would not on forehand make
+%D things more readable, so we stick to the following
+%D definitions.
+
+\startuseMPgraphic{page}
+
+ width := \overlaywidth ;
+ height := \overlayheight ;
+
+ d := 15 ; dd := d ; dd := 10 ;
+
+ def fuzzy (expr p,dx,dy) =
+ (xpart p +dx-uniformdeviate dx,ypart p+dy-uniformdeviate dy)
+ enddef ;
+
+ pair ll, lr, ur, ul ;
+
+ ll := (d,d) ;
+ lr := (width-d,d) ;
+ ur := (width-d,height-d) ;
+ ul := (d,height-d) ;
+
+ path p, q, r, s ;
+
+ p := ll.. for i=.1 step .1 until .9 : fuzzy (i[ll,lr],0,+dd).. endfor lr ;
+ q := lr.. for i=.1 step .1 until .9 : fuzzy (i[lr,ur],-dd,0).. endfor ur ;
+ r := ur.. for i=.1 step .1 until .9 : fuzzy (i[ur,ul],0,-dd).. endfor ul ;
+ s := ul.. for i=.1 step .1 until .9 : fuzzy (i[ul,ll],+dd,0).. endfor ll ;
+
+ fill unitsquare xscaled width yscaled height withcolor \MPcolor{PageColor} ;
+
+ fill p & q & r & s -- cycle withcolor \MPcolor{TextColor} ;
+
+ color c ; c := \MPcolor{LineColor} ;
+
+ draw p withpen pencircle xscaled 20 yscaled 5 rotated 30 withcolor c ;
+ draw q withpen pencircle xscaled 5 yscaled 20 rotated 30 withcolor c ;
+ draw r withpen pencircle xscaled 20 yscaled 5 rotated 30 withcolor c ;
+ draw s withpen pencircle xscaled 5 yscaled 20 rotated 30 withcolor c ;
+
+\stopuseMPgraphic
+
+\startuseMPgraphic{itemmark}
+ width := BodyFontSize ; height := width/4 ;
+ maxheight := StrutHeight ; line := 3width/2 ;
+
+ def fuzzy = -(height/4)+uniformdeviate (height/2) enddef ;
+
+ draw
+ ((0,0+fuzzy)--(width,height+fuzzy/2))
+ shifted (line/2,0)
+ withpen pencircle
+ xscaled line yscaled (line/4)
+ rotated (25+uniformdeviate 10) withcolor \MPcolor{SymbolColor} ;
+
+ setbounds currentpicture to unitsquare xyscaled(width,maxheight) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{nextmark}
+ LoadPageState ; width := BottomHeight ; height := line := width/2 ;
+
+ def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ;
+
+ z1 = (0,0+fuzzy) ; z2 = (width,height/2+fuzzy/2) ; z3 = (0,height+fuzzy) ;
+
+ draw
+ (z1..{right}z2 & z2{left}..z3)
+ withpen pencircle
+ xscaled line yscaled (line/4)
+ rotated 30 withcolor \MPcolor{SymbolColor} ;
+
+ setbounds currentpicture to unitsquare xyscaled(width,height) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{prevmark}
+ LoadPageState ; width := BottomHeight ; height := line := width/2 ;
+
+ def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ;
+
+ z1 = (width,0+fuzzy) ; z2 = (0,height/2+fuzzy/2) ; z3 = (width,height+fuzzy) ;
+
+ draw
+ (z1..{left}z2 & z2{right}..z3)
+ withpen pencircle
+ xscaled line yscaled (line/4)
+ rotated 30 withcolor \MPcolor{SymbolColor} ;
+
+ setbounds currentpicture to unitsquare xyscaled(width,height) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{stopmark}
+ LoadPageState ; width := BottomHeight ; height := line := width/2 ;
+
+ def fuzzy = -(height/8)+uniformdeviate (height/4) enddef ;
+
+ z1 = (0,0+fuzzy) ;
+ z2 = (width,height+fuzzy) ;
+ z3 = (width,0+fuzzy) ;
+ z4 = (0,height+fuzzy) ;
+ z5 = (width/2,height/2) ;
+
+ drawoptions
+ (withpen pencircle
+ xscaled line yscaled (line/4)
+ rotated 30 withcolor \MPcolor{SymbolColor}) ;
+
+ draw z1..{right}z5..z2 ; draw z3..{left}z5..z4 ;
+
+ setbounds currentpicture to unitsquare xyscaled(width,height) ;
+\stopuseMPgraphic
+
+\doifnotmode{demo}{\endinput}
+
+%D The (rather silly) demo section.
+
+\starttext
+
+\TitlePage{Title Page\\pre-writing}
+
+\Topics{Some Nice Quotes}
+
+\Topic{A Few}
+
+\Subject{Knuth} \input knuth
+\Subject{Tufte} \input tufte
+
+\Topic{Some More}
+
+\Subject{Zapf} \input zapf
+\Subject{Bryson} \input bryson
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-14.tex b/tex/context/modules/common/s-pre-14.tex
new file mode 100644
index 000000000..4dae6c009
--- /dev/null
+++ b/tex/context/modules/common/s-pre-14.tex
@@ -0,0 +1,263 @@
+%D \module
+%D [ file=s-pre-14,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 14,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D In the process of making a couple of simple styles for
+%D \EUROTEX\ 99, I came to this one. The joke is in the
+%D pagenumber. This style can be used for short presentations
+%D with much text.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+%D Since we expect text, we can best be very tolerant.
+
+\setuptolerance
+ [verytolerant,stretch]
+
+%D As most styles we choose a large screen page size.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=fit,
+ rightedge=3cm,
+ margin=0pt,
+ rightedgedistance=2cm,
+ height=middle,
+ header=0pt,
+ footer=0pt,
+ topspace=1cm,
+ backspace=1cm]
+
+%D We only use two colors, named \type {One} and \type
+%D {Two}:
+
+\setupcolors
+ [state=start]
+
+\definecolor [One] [r=.6,g=.4,b=.4]
+\definecolor [Two] [r=.4,g=.6,b=.6]
+
+%D If you've looked at the demo file, you will have noticed
+%D that the background consists of four pieces: two filled
+%D rectangles and two half numbers. These are put on th epage
+%D using four overlays:
+
+\setupbackgrounds
+ [page]
+ [background={one,two,three,four}]
+
+%D When we code this in \TEX, we get the following
+%D definitions. As an alternative we coudl have used layers
+%D but I'm afraid that it would not have led to less code.
+
+\defineoverlay
+ [one]
+ [{\framed
+ [frame=off,background=color,backgroundcolor=Two,
+ width=\overlaywidth,height=\overlayheight]
+ {}}]
+
+\defineoverlay
+ [three]
+ [{\hbox to \overlaywidth
+ {\hfill\SetOverlayWidth
+ \framed
+ [frame=off,background=color,backgroundcolor=One,
+ width=\overlaywidth,height=\overlayheight]
+ {}}}]
+
+%D We could have used the main backgroundcolor instead of
+%D overlay \type {one}.
+
+\definefont[NumberFont][RegularBold at 3cm]
+
+\defineoverlay
+ [two]
+ [{\framed
+ [frame=off,width=\overlaywidth,height=\overlayheight,
+ offset=overlay]
+ {\vfill
+ \NumberFont\setstrut\SetOverlayWidth
+ \hbox to \hsize
+ {\hfill
+ \setupinteraction[style=,color=]%
+ \setbox0=\hbox{\strut\One\pagenumber}%
+ \hbox to 0pt{\hss\gotobox{\box0}[previouspage]\hss}%
+ \hskip\overlaywidth}}}]
+
+\defineoverlay
+ [four]
+ [{\framed
+ [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay]
+ {\vfill
+ \hbox to \hsize
+ {\hfill
+ \SetOverlayWidth
+ \framed
+ [frame=off,width=\overlaywidth,height=\overlayheight,offset=overlay]
+ {\vfill\NumberFont\setstrut
+ \setbox0=\hbox{\strut\Two\pagenumber}%
+ \setbox2=\hbox{\clip[nx=2,ny=1,x=2,y=1]{\copy0}}%
+ \dp2=\dp0
+ \hbox to \hsize{\hbox to 0pt{\hss\hskip.5\wd0\box2\hss}\hfill}}}}}]
+
+\def\SetOverlayWidth%
+ {\scratchdimen = \rightedgedistance
+ \divide\scratchdimen by 2
+ \advance\scratchdimen by \rightedgewidth
+ \advance\scratchdimen by \backspace
+ \edef\overlaywidth{\the\scratchdimen}}
+
+%D A much cleaner implementation is the following. If you hate
+%D \METAPOST, you can run this style in the specified mode:
+
+\startnotmode[no-metapost]
+
+\setupbackgrounds
+ [page]
+ [background={number}]
+
+\defineoverlay[number][\useMPgraphic{number}]
+
+\startuseMPgraphic{number}
+ StartPage ;
+ path Vage ; picture Left, Right ;
+ x1 = x2 = xpart (llcorner Field[Text][RightEdge] shifted (-RightEdgeDistance/2,0)) ;
+ y1 = ypart llcorner Page ;
+ y2 = ypart ulcorner Page ;
+ Vage := llcorner Page -- z1 -- z2 -- ulcorner Page -- cycle ;
+ fill Page withcolor \MPcolor {One} ;
+ fill Vage withcolor \MPcolor {Two} ;
+ if PageNumber>0 :
+ defaultfont := "\truefontname{RegularBold}" ;
+ Left := Right := thelabel("\folio",origin) ysized 3cm ;
+ clip Right to boundingbox Right shifted (bbwidth(Right)/2,0) ;
+ draw Left shifted z1 shifted (0,2.25cm) withcolor \MPcolor {One} ;
+ draw Right shifted z1 shifted (0,2.25cm) withcolor \MPcolor {Two} ;
+ fi ;
+ StopPage ;
+\stopuseMPgraphic
+
+\stopnotmode
+
+%D We use the simple label typesetting present in \METAPOST\
+%D because digits are seldom kerned so real \TEX ing is not
+%D needed. As in the previous method, we let the graphics
+%D overlap so that we don't get white lines due to rounding
+%D problems in viewers.
+%D
+%D We put a button behind the text (this overlay is calculated
+%D each page).
+
+\defineoverlay
+ [nextpage]
+ [\overlaybutton{nextpage}]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=.5cm,
+ background=nextpage]
+
+%D We still have to turn on interaction mode.
+
+\setupinteraction
+ [state=start,
+ display=new,
+ menu=on]
+
+\setupinteraction
+ [color=,
+ contrastcolor=]
+
+%D Next we define structuring commands.
+
+\definehead[Topic] [chapter] \setuphead[Topic] [style=\bfc]
+\definehead[Subject][section] \setuphead[Subject][style=\bfa]
+
+\setuphead
+ [Topic, Subject]
+ [number=no,
+ after={\blank[big]}]
+
+%D Because we will provide a menu, we don't offer lists.
+
+\let\Topics \gobbleoneargument
+\let\Subjects\relax
+
+%D The table of contents goes to the right edge.
+
+\startinteractionmenu[right]
+ \setupinteraction
+ [color=black,
+ contrastcolor=Two]
+ \placelist
+ [Topic]
+ [alternative=e,
+ frame=off,
+ criterium=all]
+ \vfill
+\stopinteractionmenu
+
+\setuplist
+ [Topic]
+ [width=\rightedgewidth,
+ maxwidth=\rightedgewidth,
+ style=\bfa]
+
+%D We safe some space:
+
+\setupwhitespace
+ [medium]
+
+\setupblank
+ [medium]
+
+%D In the titlepage, we still use the \TEX\ overlays,
+%D so that we don't have to define a second graphic.
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\def\StartTitlePage%
+ {\bgroup
+ \setupbackgrounds[page][background={one,three}]
+ \startstandardmakeup
+ \setupalign[middle]
+ \def\\{\vfil\bfb\setupinterlinespace}
+ \bfd\setupinterlinespace
+ \vfil}
+
+\def\StopTitlePage%
+ {\vfil\vfil\vfil
+ \stopstandardmakeup
+ \egroup}
+
+%D This is it.
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\TitlePage{Some Quotes\\(that you probably know by now)}
+
+\Topic{Tufte} \input tufte
+\Topic{Knuth} \input knuth
+\Topic{Reich} \input reich
+\Topic{Zapf} \input zapf
+\Topic{Materie} \input materie
+%Topic{Stork} \input stork
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-15.tex b/tex/context/modules/common/s-pre-15.tex
new file mode 100644
index 000000000..25fb35783
--- /dev/null
+++ b/tex/context/modules/common/s-pre-15.tex
@@ -0,0 +1,186 @@
+%D \module
+%D [ file=s-pre-15,
+%D version=1999.09.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 15,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is one of the styles I made for the presentation on
+%D the \NTS\ project at Euro\TeX\ 1998. You need balls to let
+%D \TEX\ typeset graphics, but this style demonstrates that it
+%D can be done.
+%D
+%D This presentation is meant for presentations that build up
+%D an idea stepwise.
+%D
+%D \starttyping
+%D \TitlePage{Do you know \TEX ?}
+%D
+%D \StartIdea
+%D \StartItem We use \TEX\ for typesetting \unknown \StopItem
+%D \StartItem mathematical text \unknown \StopItem
+%D \StartItem but also for text that has no math \unknown \StopItem
+%D \StartItem or presentations like this \unknown \StopItem
+%D \StartItem and whatever you can come up with! \StopItem
+%D \StopIdea
+%D \stoptyping
+
+%D The basic layout is rather simple and used as much of the
+%D screen as possible.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [backspace=25pt,
+ topspace=25pt,
+ width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt]
+
+\setupinteraction
+ [state=start,
+ display=new,
+ color=LineColor,
+ contrastcolor=LineColor,
+ click=no]
+
+\setupinteractionscreen
+ [option=max]
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+%D We use a lot of color. You can remap them if you want
+%D differend ones. The ideas circulate over the colors.
+
+\setupcolors
+ [state=start]
+
+\definecolor[TextColor][s=.8]
+\definecolor[PageColor][s=.6]
+\definecolor[LineColor][s=.4]
+
+\definecolor[red] [r=.4] \definecolor[cyan] [g=.4,b=.4]
+\definecolor[green][g=.4] \definecolor[magenta][r=.4,b=.4]
+\definecolor[blue] [b=.4] \definecolor[yellow] [r=.4,g=.4]
+
+\definecolor[linecolor 1][red] \definecolor[linecolor 5][cyan]
+\definecolor[linecolor 2][green] \definecolor[linecolor 6][magenta]
+\definecolor[linecolor 3][blue] \definecolor[linecolor 4][yellow]
+
+%D We use variables to make sure that the graphics are reused
+%D but unique.
+
+\setupMPvariables[pageframe][pagecolor=PageColor,linecolor=LineColor]
+\setupMPvariables[textframe][textcolor=TextColor,linecolor=LineColor]
+
+\setupbackgrounds
+ [page]
+ [background={pageframe,nextpage}]
+
+\defineoverlay [pageframe] [\uniqueMPgraphic{pageframe}]
+\defineoverlay [textframe] [\uniqueMPgraphic{textframe}]
+\defineoverlay [nextpage] [\overlaybutton{forward}]
+
+\startuniqueMPgraphic{pageframe}{pagecolor,linecolor}
+ path p ; p := fullsquare xyscaled (\overlaywidth,\overlayheight) ;
+ pickup pencircle scaled 10pt ;
+ fill p withcolor \MPvar{pagecolor} ;
+ draw p withcolor \MPvar{linecolor} ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{textframe}{textcolor,linecolor}
+ path p ; p := fullcircle xyscaled (\overlaywidth,\overlayheight) ;
+ pickup pencircle scaled 10pt ;
+ fill p withcolor \MPvar{textcolor} ;
+ draw p withcolor \MPvar{linecolor} ;
+\stopuniqueMPgraphic
+
+%D The rest of the file implements the nasty part: typesetting
+%D text embedded in a graphic. The text is collected in a box
+%D so that we can reuse it.
+
+\newbox\CollectedIdeas
+\newcounter\CurrentTopic
+
+\def\StartItem%
+ {\setbox\CollectedIdeas=\hbox\bgroup
+ \ifdim\wd\CollectedIdeas>0pt \unhbox\CollectedIdeas\hskip25pt \fi
+ \setbox\scratchbox=\hbox\bgroup
+ \framed
+ [width=160pt,height=160pt,align=middle,frame=off,
+ background=textframe,offset=15pt,top=\vfill,bottom=\vfill]
+ \bgroup}
+
+\def\StopItem%
+ {\egroup
+ \egroup
+ \setbox\scratchbox=\hbox{\lower.5\ht\scratchbox\box\scratchbox}%
+ \ht\scratchbox=.5\ht\scratchbox
+ \dp\scratchbox= \ht\scratchbox
+ \box\scratchbox
+ \egroup
+ \startstandardmakeup
+ \dontcomplain
+ \leftskip 0pt plus 50pt
+ \rightskip 0pt plus 50pt
+ \parfillskip 0pt
+ \baselineskip 100pt
+ \unhcopy\CollectedIdeas
+ \stopstandardmakeup}
+
+\def\StartIdea%
+ {\ifnum\CurrentTopic=6 \doglobal\newcounter\CurrentTopic \fi
+ \doglobal\increment\CurrentTopic
+ \definecolor[LineColor][linecolor \CurrentTopic]
+ \setbox\CollectedIdeas=\null}
+
+\def\StopIdea%
+ {}
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \setupalign[middle]
+ \def\\{\vfil\bfb\setupinterlinespace}
+ \bfd\setupinterlinespace
+ \vfil}
+
+\def\StopTitlePage%
+ {\vfil\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\doifnotmode{demo}{\endinput}
+
+%D A simple test on functionality.
+
+\setupoutput[pdftex]
+
+\starttext
+
+\TitlePage{Do you know \TEX ?}
+
+\startbuffer
+\StartIdea
+ \StartItem We use \TEX\ for typesetting \unknown \StopItem
+ \StartItem mathematical text \unknown \StopItem
+ \StartItem but also for text that has no math \unknown \StopItem
+ \StartItem or presentations like this \unknown \StopItem
+ \StartItem and whatever you can come up with! \StopItem
+\StopIdea
+\stopbuffer
+
+\dorecurse{6}{\getbuffer}
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-16.tex b/tex/context/modules/common/s-pre-16.tex
new file mode 100644
index 000000000..715936890
--- /dev/null
+++ b/tex/context/modules/common/s-pre-16.tex
@@ -0,0 +1,203 @@
+%D \module
+%D [ file=s-pre-16,
+%D version=1999.09.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 16,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The first version of this style was made late summer 1999,
+%D but its first usage was during a course I gave in BRNO.
+%D It's a rather simple style with a dominating background.
+
+\setuppapersize
+ [S6][S6]
+
+\setupbodyfont
+ [pos,14.4pt]
+
+\setuplayout
+ [topspace=100pt,
+ backspace=120pt,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=80pt,
+ background=GoOn]
+
+\setupbackgrounds
+ [page]
+ [background={FuzzyCircle,Again}]
+
+\setupcolors
+ [state=start]
+
+\definecolor[gray] [s=.4]
+\definecolor[white][s=.8]
+
+\definecolor[red] [r=.8] \definecolor[cyan] [g=.8,b=.8]
+\definecolor[green][g=.8] \definecolor[magenta][r=.8,b=.8]
+\definecolor[blue] [b=.8] \definecolor[yellow] [r=.8,g=.8]
+
+\definecolor[PageColor][gray]
+\definecolor[TextColor][yellow]
+\definecolor[LineColor][blue]
+
+\setupinteraction
+ [state=start,
+ color=LineColor,
+ contrastcolor=LineColor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupitemize
+ [each]
+ [color=blue,
+ symbol=FuzzyDot]
+
+\startuseMPgraphic{FuzzyCircle}
+ path p ; numeric w, h, l ;
+ w := OverlayWidth ; h := OverlayHeight ;
+ def dd = (1 randomized (1/5)) enddef ;
+ pickup pencircle xscaled 10pt yscaled 2pt rotated 30;
+ for i:=1 upto 50 :
+ p := (-dd,-dd)..(dd,-dd)..(dd,dd)..(-dd,dd)..cycle ;
+ p := p rotatedaround (center p, uniformdeviate 360) ;
+ p := p xscaled (w/2) yscaled (h/2) ;
+ l := length(p)/2 ;
+ p := p cutbefore point (uniformdeviate l) of p ;
+ p := p cutafter point (l+uniformdeviate l) of p ;
+ draw p withcolor \MPcolor{LineColor} randomized (.4,1) ;
+ endfor ;
+ picture s ; s := currentpicture xysized (w-15,h-15) ;
+ currentpicture := nullpicture ;
+ fill boundingbox s enlarged 60pt withcolor \MPcolor{PageColor} ;
+ addto currentpicture also s ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{FuzzyDot}
+ path p ; numeric w ;
+ w := BodyFontSize/2 ;
+ def dd = (w randomized (w/2)) enddef ;
+ pickup pencircle xscaled (w/2) yscaled (w/3) rotated 30 ;
+ for i=0 step 45 until 135 :
+ p := (-dd,0)--(dd,0) ;
+ p := p rotatedaround (origin,i-w+uniformdeviate w) ;
+ draw p withcolor \MPcolor{LineColor} randomized (.3,.8) ;
+ endfor ;
+\stopuseMPgraphic
+
+\defineoverlay [FuzzyCircle] [\useMPgraphic{FuzzyCircle}]
+\defineoverlay [GoOn] [{\setupinteraction[click=no]\overlaybutton{forward}}]
+\defineoverlay [Again] [\overlaybutton{firstpage}]
+
+\definesymbol
+ [FuzzyDot]
+ [\lower\dp\strutbox\hbox{\useMPgraphic{FuzzyDot}}]
+
+\def\Item%
+ {\par\noindent\symbol[FuzzyDot]\hskip.5em\nobreak}
+
+\setupitemize
+ [all]
+ [packed]
+ [symbol=FuzzyDot]
+
+\def\NextIdea%
+ {\blank[back,medium]
+ \midaligned{\symbol[FuzzyDot]}
+ \blank[medium]
+ \blank[disable]}
+
+\definehead [Topic] [chapter]
+\definehead [Nopic] [title]
+
+\setuphead
+ [Topic, Nopic]
+ [alternative=middle,
+ before=,
+ number=no,
+ style=\bfb]
+
+\setuplist
+ [Topic]
+ [alternative=g,
+ interaction=all]
+
+%D Since we want a colored text, and since color directive
+%D can spoil the spacing, we use a foregroundcolor.
+
+\setupbackgrounds
+ [text]
+ [foregroundcolor=TextColor]
+
+%D Unfortunately this does not work when on the page colors
+%D are set, so we play safe and say:
+
+\setupmakeup
+ [standard]
+ [color=TextColor]
+
+\def\StartIdea%
+ {\startstandardmakeup
+ \setupwhitespace[medium]
+ \setupblank[medium]
+ \setupalign[broad,middle]}
+
+\def\StopIdea%
+ {\stopstandardmakeup}
+
+\def\Topics#1%
+ {\Nopic{#1}
+ \startcolumns
+ \setupinteraction[color=TextColor,contrastcolor=TextColor]
+ \placelist[Topic]
+ \stopcolumns
+ \page}
+
+%D Some fakes.
+
+\def\Subject {\Topic}
+\def\Subjects {}
+
+%D A bonus (copied from \type {s-pre-02} but with a different
+%D vertical alignment.
+
+\def\StartTitlePage%
+ {\startstandardmakeup
+ \bfd\setupinterlinespace
+ \setupalign[middle]
+ \vfil
+ \let\\=\vfil}
+
+\def\StopTitlePage%
+ {\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\Topics{...}
+
+\StartIdea
+ \Topic{...}
+ ...
+ \NextIdea
+ ...
+\StopIdea
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-18.tex b/tex/context/modules/common/s-pre-18.tex
new file mode 100644
index 000000000..876eec5f1
--- /dev/null
+++ b/tex/context/modules/common/s-pre-18.tex
@@ -0,0 +1,173 @@
+%D \module
+%D [ file=s-pre-18,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 18,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: met pos en dan iedere titel
+
+\setuppapersize
+ [S6][S6]
+
+\setupbodyfont
+ [loc,ppl]
+
+\setupcolors
+ [state=start]
+
+\definecolor [shade-1] [s=.7]
+\definecolor [shade-2] [s=.1]
+
+\definecolor [shade-3] [s=.8]
+\definecolor [shade-4] [b=.8]
+
+\definecolor [shade-5] [g=.6]
+
+\setuplayout
+ [topspace=1cm,
+ height=fit,
+ backspace=1cm,
+ width=middle,
+ header=0pt,
+ footer=0pt,
+ bottomdistance=1cm]
+
+\setupbackgrounds
+ [state=repeat]
+
+\setupbackgrounds [page] [background=page]
+
+\defineoverlay [page] [\useMPgraphic{page}]
+\defineoverlay [text] [\useMPgraphic{text}]
+
+\startuseMPgraphic{page}
+ StartPage ;
+ path p ; numeric s ; pair cp ; cp := center Page ;
+ s := define_circular_shade(cp,cp,0,TextWidth,
+ \MPcolor{shade-1},\MPcolor{shade-2}) ;
+ fill Page withshade s ;
+ p := fullcircle xyscaled (TextWidth+1cm, TextHeight+1cm) shifted cp ;
+ s := define_circular_shade(cp,cp,0,TextWidth,\MPcolor{shade-3},
+ \MPcolor{shade-4}) ;
+ fill p withshade s ;
+ StopPage
+\stopuseMPgraphic
+
+\startuseMPgraphic{text}
+ StartPage ;
+ path p ; numeric s, t ; pair cp ; cp := center Page ;
+ s := define_circular_shade(cp,cp,0,TextWidth,
+ \MPcolor{shade-1},\MPcolor{shade-2}) ;
+ fill Page withshade s ;
+ p := llcorner Field[Text][Bottom] --
+ lrcorner Field[Text][Bottom] --
+ urcorner Field[Text][Text] --
+ ulcorner Field[Text][Text] -- cycle ;
+ p := p enlarged .5cm randomized .5cm ;
+ t := define_circular_shade(cp,cp,0,TextWidth,\MPcolor{shade-3},
+ \MPcolor{shade-4}) ;
+ fill p withshade t ;
+
+ def bottom_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ if nn = 1 :
+ p := (0,0)--(ww,hh/2)--(0,hh)--cycle ;
+ elseif nn = 2 :
+ p := (0,hh/2)--(ww,hh)--(ww,0)--cycle ;
+ else :
+ p := origin--cycle ;
+ fi ;
+ fill p randomized 2.5mm shifted (xx,yy) withshade s ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{bottom}
+
+ if length \MPstring{topic} > 0 :
+ graphictext
+ \MPstring{topic}
+ scaled 3
+ shifted ulcorner Field[Text][Text]
+ shifted (0,-1.5cm)
+ withshade s ;
+ fi ;
+
+ StopPage ;
+\stopuseMPgraphic
+
+\setupinteractionmenu
+ [bottom]
+ [state=start,
+ frame=off,
+ left=\hfill,
+ middle=\hskip.5cm,
+ width=2\bottomheight,
+ position=yes]
+
+\startinteractionmenu[bottom]
+ \but [previouspage] \\
+ \but [nextpage] \\
+\stopinteractionmenu
+
+\setupinteraction
+ [state=start,
+ click=no,
+ color=shade-5,
+ contrastcolor=shade-5,
+ menu=on]
+
+\setupwhitespace
+ [big]
+
+\def\Topic#1%
+ {\page
+ \setMPtext{topic}{#1}
+ \vbox to 2cm{}}
+
+\setMPtext{topic}{}
+
+\def\StartTitlePage%
+ {\startstandardmakeup[bottomstate=none]
+ \setupalign[middle]
+ \vfill}
+
+\def\StopTitlePage%
+ {\stopstandardmakeup
+ \setuplayout[bottom=1.5cm]
+ \setupbackgrounds[page][background=text]}
+
+\def\TitleString#1#2%
+ {\indent
+ \startMPcode
+ graphictext
+ "#2"
+ scaled #1
+ withdrawcolor .4white
+ withfillcolor .7white
+ withpen pencircle scaled 2pt ;
+ \stopMPcode
+ \vfill}
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\StartTitlePage
+ \TitleString{8}{Welcome}
+ \TitleString{4}{to my favourite}
+ \TitleString{8}{Quotes}
+\StopTitlePage
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-19.tex b/tex/context/modules/common/s-pre-19.tex
new file mode 100644
index 000000000..991d311ce
--- /dev/null
+++ b/tex/context/modules/common/s-pre-19.tex
@@ -0,0 +1,347 @@
+%D \module
+%D [ file=s-pre-19,
+%D version=2000.07.31,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 19,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style is made in the process or writing the \METAFUN\
+%D manual. It exploits a few tricks, like graphics calculated
+%D using positional information. It also uses the (at that
+%D moment) new menu list placement alternative. If you forget
+%D about the definition of the button shapes, which is
+%D complicated in any system, this style is not even that hard
+%D to follow. Watch how the left side of the buttons follow
+%D the right side of the text graphic.
+%D
+%D While playing bit with this style, the random alternative
+%D made me think of those organic building with non equal
+%D windows (we have a few in The Netherlands), so I decided to
+%D label this style as \type {pre-organic}.
+%D
+%D At the end of this file, there is a small test file, so
+%D when you process this file with \TEXEXEC\ and the options
+%D \type {--mode=demo} and \type {--pdf}, you will get a demo
+%D document.
+
+%D We use one of the standard screen \quote {paper} sizes, and
+%D map it onto the same size, so that we get a nicely cropped
+%D page.
+
+\setuppapersize
+ [S6][S6]
+
+%D Like in the \METAFUN\ manual, we use the Palatino as main
+%D bodyfont. This font is quite readable on even low
+%D resolution screens, although I admit that this style is
+%D developed using an $1400\times1050$ pixel LCD screen, so I
+%D may be biased.
+
+%\startmode[asintended] \setupbodyfont[ppl] \stopmode
+
+%D The layout specification sets up a text area and a right
+%D edge area where the menus will go. Watch the rather large
+%D edge distance. By setting the header and footer dimensions
+%D to zero, we automatically get rid of page body ornaments,
+%D like the pagenumber.
+
+\setuplayout
+ [topspace=48pt,
+ backspace=48pt,
+ cutspace=12pt,
+ width=400pt,
+ margin=0cm,
+ rightedge=88pt,
+ rightedgedistance=48pt,
+ header=0cm,
+ footer=0cm,
+ height=middle]
+
+%D We use a moderate, about a line height, interparagraph
+%D white space.
+
+\setupwhitespace
+ [big]
+
+%D Of course we use colors, since on computer displays they
+%D come for free.
+
+\setupcolors
+ [state=start]
+
+\definecolor [red] [r=.75]
+\definecolor [yellow] [r=.75,g=.75]
+\definecolor [gray] [s=.50]
+\definecolor [white] [s=.85]
+
+\definecolor [PageColor] [yellow]
+\definecolor [TextColor] [white]
+\definecolor [OrnamentColor] [red]
+\definecolor [InteractionColor] [red]
+\definecolor [ContrastColor] [gray]
+
+%D This is an interactive document, so we enable interaction.
+%D In this style, we disable the viewer's \quote {highlight a
+%D hyperlink when it's clicked on} feature. We will use a
+%D menu, so we enable menus. Later we will see the contract
+%D color |<|hyperlinks gets that color when we are already on
+%D the location|>| in action.
+
+\setupinteraction
+ [state=start,
+ click=off,
+ color=InteractionColor,
+ contrastcolor=ContrastColor,
+ menu=on]
+
+%D The menu itself is set up as follows. Because we will
+%D calculate menubuttons based on their position on the page,
+%D we have to keep track of the positions. Therefore, we set
+%D the \type {position} variable to \type {yes}.
+
+\setupinteractionmenu
+ [right]
+ [frame=off,
+ position=yes,
+ align=middle,
+ topoffset=-.75cm,
+ bottomoffset=-.75cm,
+ color=gray,
+ contrastcolor=gray,
+ style=bold,
+ before=,
+ after=]
+
+%D The menu content is rather sober: a list of topics (later
+%D we will define the command that generates topic entries),
+%D and a close button.
+
+\startinteractionmenu[right]
+ \placelist[Topic][alternative=right]
+ \vfill
+ \but [CloseDocument] close \\
+\stopinteractionmenu
+
+%D We have now arived at the more interesting part of the style
+%D definition: the graphic that goes in the page background.
+%D Because this graphic will change, we define a usable
+%D \METAPOST\ graphic. Page backgrounds are recalculated each
+%D page, opposite to the other backgrounds that are calculated
+%D when a new background is defined, or when repetitive
+%D calculation is turned on.
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\defineoverlay
+ [page]
+ [\useMPgraphic{page}]
+
+\setupMPvariables
+ [page]
+ [alternative=3]
+
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ path p, q ; pickup pencircle scaled 3pt ;
+
+ p := Field[Text][Text] enlarged 36pt superellipsed .90 ;
+
+ fill Page withcolor \MPcolor{PageColor} ;
+ fill p withcolor \MPcolor{TextColor} ;
+ draw p withcolor \MPcolor{OrnamentColor} ;
+
+ p := Field[Text][Text] enlarged 48pt superellipsed .90 ;
+
+ def right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ;
+ fill q withcolor \MPcolor{TextColor} ;
+ draw q withcolor if rr=2 : \MPcolor{ContrastColor}
+ else : \MPcolor{InteractionColor} fi ;
+ fi ;
+ enddef ;
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{page}
+
+ \includeMPgraphic{rightsuperbutton}
+
+ StartPage ;
+
+ numeric alternative, seed, superness, squeezeness, randomness ;
+ path p, q ; transform t ;
+
+ alternative := \MPvar{alternative} ;
+ seed := uniformdeviate 100 ;
+
+ if alternative > 10 :
+ superness := .85 + ((\realfolio-1)/\lastpage) * .15 ;
+ squeezeness := 12pt - ((\realfolio-1)/\lastpage) * 10pt ;
+ else :
+ superness := .90 ;
+ squeezeness := 12pt ;
+ fi ;
+
+ randomness := squeezeness ;
+
+ alternative := alternative mod 10 ;
+
+ t := identity if alternative=3: shifted (9pt,-9pt) fi ;
+
+ % first we draw the shape that surrounds the text
+
+ randomseed := seed ;
+
+ p := Field[Text][Text] enlarged if
+ alternative = 1 : 36pt superellipsed superness elseif
+ alternative = 2 : 36pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 36pt fi ;
+ pickup pencircle scaled 3pt ;
+
+ fill Page withcolor \MPcolor{PageColor} ;
+ fill p withcolor \MPcolor{TextColor} ;
+ draw p withcolor \MPcolor{OrnamentColor} ;
+
+ % we set p to the wider shape from which we will chip off pieces
+
+ randomseed := seed ;
+
+ p := ( Field[Text][Text] enlarged if
+ alternative = 1 : 48pt superellipsed superness elseif
+ alternative = 2 : 48pt squeezed squeezeness elseif
+ alternative = 3 : 36pt randomized randomness else
+ : 48pt fi ) transformed t ;
+
+ % calls to *_menu_button are generated automatically ...
+
+ vardef right_menu_button (expr nn, rr, pp, xx, yy, ww, hh, dd) =
+ save q ; path q ;
+ if (pp>0) and (rr>0) :
+ q := rightsuperbutton(p,xx,yy,RightEdgeWidth,hh) ; % \MPw{menu:right:\realfolio}
+ fill q withcolor \MPcolor{TextColor} ;
+ draw q withcolor if rr=2 : \MPcolor{ContrastColor}
+ else : \MPcolor{InteractionColor} fi ;
+ fi ;
+ enddef ;
+
+ % ... and inserted when the graphic data is flushed here ...
+
+ \MPmenubuttons{right}
+
+ StopPage ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{rightsuperbutton}
+
+vardef rightsuperbutton (expr pat, xpos, ypos, wid, hei) =
+
+ save p, ptop, pbot, t, b, edge, shift, width, height ;
+ path p, ptop, pbot ; pair t, b ; numeric edge, shift, width, height ;
+
+ edge := xpos + wid ; shift := ypos + hei ;
+
+ p := rightpath pat ;
+
+ ptop := ((-infinity,shift)--(edge,shift)) ;
+ pbot := ((-infinity,shift-hei)--(edge,shift-hei)) ;
+
+ t := p intersection_point ptop ;
+ b := p intersection_point pbot ;
+
+ p := subpath(0,xpart (p intersectiontimes ptop)) of p ;
+ p := subpath(xpart (p intersectiontimes pbot),length(p)) of p ;
+
+ (p -- t -- point 1 of ptop &
+ point 1 of ptop -- point 1 of pbot &
+ point 1 of pbot -- b
+ -- cycle)
+
+enddef ;
+
+\stopuseMPgraphic
+
+%D Topics are identified with \type {\Topic}, which is an
+%D instance of chapter headings. The number is made invisible.
+%D Since it still is a numbered section header, \CONTEXT\ will
+%D write the header to the table of contents.
+
+\definehead
+ [Topic]
+ [chapter]
+
+\setuphead
+ [Topic]
+ [number=no]
+
+%D We will use a bold font in the table of contents. We also
+%D force a complete list.
+
+\setuplist
+ [Topic]
+ [criterium=all,
+ style=bold,
+ before=,
+ after=]
+
+%D The \type {\TitlePage} macro looks horrible, because we
+%D want to keep the interface simple: a list of small
+%D sentences, separated by \type {\\}.
+
+\def\StartTitlePage
+ {\startstandardmakeup
+ \switchtobodyfont[big]
+ \def\\{\vfill\bfb\let\\=\par}
+ \bfd\setupinterlinespace\gray
+ \vskip.5cm}
+
+\def\StopTitlePage
+ {\\\vskip.5cm % the \\ is really needed
+ \stopstandardmakeup}
+
+\def\TitlePage#1%
+ {\StartTitlePage#1\StopTitlePage}
+
+%D A couple of goodies:
+
+\def\Subject {\Topic}
+\def\Topics #1{}
+\def\Subjects {}
+
+%D For those who want to test:
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\setupMPvariables[page][alternative=3]
+
+\TitlePage
+ {A Few Nice Quotes\\
+ A Simple Style Demo\\
+ Hans Hagen, August 2000}
+
+
+\Topic {Douglas R. Hofstadter} \input douglas \page
+\Topic {Donald E. Knuth} \input knuth \page
+\Topic {Edward R. Tufte} \input tufte \page
+\Topic {Hermann Zapf} \input zapf \page
+%Topic {David F. Stork} \input stork \page
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-22.tex b/tex/context/modules/common/s-pre-22.tex
new file mode 100644
index 000000000..be50ae195
--- /dev/null
+++ b/tex/context/modules/common/s-pre-22.tex
@@ -0,0 +1,319 @@
+%D \module
+%D [ file=s-pre-22,
+%D version=2000.08.07,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 22,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style was made on behalf of the \PDFTEX\ presentation
+%D at \TUG\ 2000. It cycled a summary of each talk, with name
+%D and title. When documenting this style, I changed
+%D reprocessing into pushing on layers.
+%D
+%D A \quote {problem} like this can be solved in several ways:
+%D
+%D \startitemize
+%D \item writing a lot of semi||complex \TEX\ code as shown
+%D \item keeping track of positions and draw everything on the
+%D page layer
+%D \item defining an overlay for each summary and changing the
+%D order when flushing
+%D \item maintaining a so called field stack
+%D \stopitemize
+%D
+%D We go for the first method. We assume that summaries are
+%D simple text snippets.
+
+\startmode[asintended] \setupbodyfont[lbr] \stopmode
+
+\setupbodyfont[14.4pt]
+
+%D We use the whole page area.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+%D We define a couple of matching colors and gray scales.
+%D Watch out, some are really meant to look dim.
+
+\setupcolors
+ [state=start]
+
+\definecolor[PageColor] [s=.50]
+\definecolor[TextColor] [s=.80]
+\definecolor[DoneColor] [s=.65]
+
+\definecolor[TopColor] [r=.5,g=.6,b=.7]
+\definecolor[BotColor] [r=.6,g=.7,b=.5]
+\definecolor[DotColor] [r=.7,g=.5,b=.6]
+
+%D We will use foreground colors. Because these can interfere
+%D with the colors they overload, we can bets make sure that
+%D we don't have local colors.
+
+\setupinteraction
+ [state=start,
+ color=,
+ contrastcolor=]
+
+%D The presentation is supposed to cycle automatically.
+
+\setupinteractionscreen
+ [option=max,
+ delay=5]
+
+\setuppagetransitions
+
+%D We will use random positioning of objects.
+
+\setupsystem
+ [random=medium]
+
+%D We have two kind of graphics: the page background and
+%D the shape around the textual elements.
+
+\defineoverlay [shape] [\uniqueMPgraphic{shape}]
+\defineoverlay [page] [\reuseMPgraphic{page}]
+
+\startreusableMPgraphic{page}
+ StartPage ;
+ filldraw Page withcolor \MPcolor{PageColor} ;
+ pickup pencircle scaled .375cm ;
+ for i=1 upto 200 :
+ drawdot center Page randomized (PaperWidth,PaperHeight)
+ withcolor \MPcolor {DotColor} ;
+ endfor ;
+ StopPage ;
+\stopreusableMPgraphic
+
+\startuniqueMPgraphic{shape}
+ path p ;
+ p := unitsquare xyscaled(OverlayWidth,OverlayHeight) superellipsed .90 ;
+ draw p withpen pencircle scaled .50cm withcolor \MPcolor{PageColor} ;
+ fill p withcolor OverlayColor ;
+ draw p withpen pencircle scaled .25cm withcolor OverlayLineColor ;
+ currentpicture := currentpicture xysized(OverlayWidth,OverlayHeight) ;
+\stopuniqueMPgraphic
+
+%D The resizing at the end is needed to get a nice inverted
+%D hyperlink when we click on it in a browser.
+
+%D Behind the page we put a forward button:
+
+\defineoverlay [forward] [\overlaybutton{forward}]
+
+%D The content will be managed by means of two layers.
+
+\definelayer [main] \defineoverlay [main] [\composedlayer{main}]
+\definelayer [temp] \defineoverlay [temp] [\composedlayer{temp}]
+
+%D The first layer will hold everything to be shown, while
+%D the second one gets the data we currently focus on.
+%D Therefore the first layer will not be flushed each page.
+
+\setuplayer
+ [main]
+ [state=repeat]
+
+%D All the overlays go onto the page area.
+
+\setupbackgrounds
+ [page]
+ [background={page,forward,main,temp}]
+
+%D We have to collect all data before we typeset it. Each
+%D element will be typeset dim and bright. The dim
+%D alternatives will be collected on the main layer, but each
+%D bring one goes onto a box stack.
+
+\initializeboxstack{Summary}
+\initializeboxstack{Subtext}
+
+%D The macros that take care of all this manipulations look
+%D more complicated than they actually are. We use a
+%D scratchbox to collect and inspect data. Also, because we
+%D typeset each element twice, we need to make sure that we use
+%D the same random seed for both.
+
+\doglobal\newcounter\CurrentSummary
+
+\def\StartSummary% bottom bot-title top-title
+ {\dodoublegroupempty\doStartSummary}
+
+\def\doStartSummary#1#2%
+ {\doglobal\increment\CurrentSummary
+ \setbox\scratchbox=\hbox{\strut#1}
+ \getrandomseed\RandomSeed
+ \setlayer[main]
+ {\RandomSubtextBox{DoneColor}{BotColor}{BotColor}}
+ \setrandomseed\RandomSeed
+ \savebox{Subtext}{\CurrentSummary}
+ {\RandomSubtextBox{TextColor}{BotColor}{black}}
+ \setbox\scratchbox=\hbox \bgroup
+ \setbox\scratchbox=\hbox{\bfb\setstrut\strut\quad#2\quad}%
+ \SetAcceptableWidth
+ \framed [offset=0pt,width=fit,frame=off,align=middle,strut=no]
+ \bgroup \setupwhitespace[big]
+ \doifsomething{#2}{\noindent\box\scratchbox\blank}}
+
+\def\StopSummary
+ {\egroup \egroup
+ \getrandomseed\RandomSeed
+ \setlayer[main]
+ {\RandomSummaryBox{DoneColor}{TopColor}{TopColor}}
+ \setrandomseed\RandomSeed
+ \savebox{Summary}{\CurrentSummary}
+ {\RandomSummaryBox{TextColor}{TopColor}{black}}}
+
+%D A \type {\doStartSummary#1#2#3\StopSummary} could have been
+%D used too but this one is less sensitive for catcode changes
+%D (not that we expect problems like this in this kind of
+%D application).
+
+%D The width is either derived from the width ot the title or
+%D at random. The final width of the box is detemined by the
+%D content.
+
+\def\SetAcceptableWidth
+ {\scratchdimen=.5\makeupwidth
+ \ifdim\wd\scratchbox>.5\makeupwidth
+ \getrandomdimen\hsize{\wd\scratchbox}{.8\makeupwidth}%
+ \else
+ \getrandomdimen\hsize{.5\makeupwidth}{.7\makeupwidth}%
+ \fi}
+
+%D The subtext box goes at the bottom, somewhere in the right
+%D corner.
+
+\def\RandomSubtextBox#1#2#3%
+ {\vbox to \makeupheight
+ {\vfill
+ \hbox to \makeupwidth
+ {\hfill
+ \button
+ [offset=2ex,frame=off,background=shape,strut=no,
+ backgroundcolor=#1,framecolor=#2,foregroundcolor=#3]
+ {\copy\scratchbox}%
+ [previouspage]%
+ \getrandomdimen\scratchdimen{.5cm}{2.5cm}%
+ \hskip\scratchdimen}
+ \getrandomdimen\scratchdimen{.5cm}{1.5cm}
+ \vskip \scratchdimen}}
+
+%D The main text goes in the top half of the page, not to
+%D far from the center. The last \type {\vskip} makes sure
+%D that we don't clash with the subtexts.
+
+\definereference[thispage][page(\CurrentSummary)]
+
+\def\RandomSummaryBox#1#2#3%
+ {\vbox to \makeupheight
+ {\getrandomdimen\scratchdimen{.5cm}\makeupheight
+ \vskip 0pt plus \scratchdimen
+ \hbox to \makeupwidth
+ {\getrandomdimen\scratchdimen{.5cm}\makeupwidth
+ \hskip 0pt plus \scratchdimen
+ \button
+ [offset=3ex,frame=off,background=shape,strut=no,
+ backgroundcolor=#1,framecolor=#2,foregroundcolor=#3]
+ {\copy\scratchbox}%
+ [thispage]%
+ \getrandomdimen\scratchdimen{.5cm}\makeupwidth
+ \hskip 0pt plus \scratchdimen}
+ \getrandomdimen\scratchdimen{.5cm}\makeupheight
+ \vskip 0pt plus \scratchdimen
+ \vskip.2\makeupheight}}
+
+%D Because we conly collect data, we hav eto make sure that at
+%D some moment it is processed and flushed. The following loop
+%D does this.
+
+\def\BuildPage
+ {\dorecurse{\CurrentSummary}
+ {\startstandardmakeup
+ \setlayer[temp]{\foundbox{Summary}\recurselevel}
+ \setlayer[temp]{\foundbox{Subtext}\recurselevel}
+ \stopstandardmakeup}}
+
+%D We hook this macro into the \type {\stoptext} macro.
+
+\appendtoks \BuildPage \to \everystoptext
+
+%D We still need a title page.
+
+\def\TitlePage%
+ {\dodoublegroupempty\doTitlePage}
+
+\long\def\doTitlePage#1#2%
+ {\ifsecondargument
+ \MakeTitlePage{#1}{#2}
+ \else\iffirstargument
+ \MakeTitlePage{\currentdate}{#1}
+ \else
+ \MakeTitlePage{\currentdate}{Welcome}
+ \fi\fi}
+
+\def\MakeTitlePage#1#2%
+ {\StartSummary{#1}{#2}\StopSummary}
+
+%D For old times sake:
+
+\long\def\StartTopic#1\StopTopic{\StartSummary#1\StopSummary}
+
+\doifnotmode{demo}{\endinput}
+
+%D The demo text.
+
+\starttext
+
+\TitlePage{Indeed}{The Title Page}
+
+\StartSummary{Alpha}{Title}
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\StartSummary{Beta and Gamma}{Another Title}
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\StartSummary{Delta}{Some Title}
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\StartSummary{Epsilon}{What A Title}
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\StartSummary{Zeta, Eta and Theta}{Eh, A Title}
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\StartSummary{Omega}
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+ A simple and not too long text just to show the topic.
+\StopSummary
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-23.tex b/tex/context/modules/common/s-pre-23.tex
new file mode 100644
index 000000000..f9983a89e
--- /dev/null
+++ b/tex/context/modules/common/s-pre-23.tex
@@ -0,0 +1,109 @@
+%D \module
+%D [ file=s-pre-20,
+%D version=2000.08.07,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 20,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style looks a lot like number 22. This time we don't
+%D cycle but build up the page. One can click on the text go
+%D to the page wanted. Clicking on the titl ebrings you to the
+%D previous page.
+
+\startmode [demo]
+ \disablemode[demo] \usemodule[pre-22] \enablemode[demo]
+\stopmode
+
+\startnotmode [demo]
+ \usemodule[pre-22]
+\stopnotmode
+
+%D We use a simple two||color scheme.
+
+\definecolor[DotColor][r=.5,g=.6,b=.7]
+\definecolor[TopColor][r=.7,g=.6,b=.5]
+\definecolor[BotColor][TopColor]
+
+%D We will not delay page building.
+
+\let\BuildPage\relax
+
+%D Instead, we will flush a page for each summary. The main
+%D layer is build up anyway, but we need to overlay the
+%D current summary.
+
+\let\normalStartSummary\StartSummary
+\let\normalStopSummary \StopSummary
+
+\def\StartSummary
+ {\startstandardmakeup
+ \normalStartSummary}
+
+\def\StopSummary
+ {\normalStopSummary
+ \setlayer[temp]{\foundbox{Summary}\CurrentSummary}
+ \setlayer[temp]{\foundbox{Subtext}\CurrentSummary}
+ \stopstandardmakeup}
+
+%D The title page is not added to the main layer (or
+%D actually, it is, but we erase the layer before it's
+%D used).
+
+\long\def\MakeTitlePage#1#2%
+ {\startstandardmakeup
+ \definereference[thispage][]
+ \switchtobodyfont[32pt]
+ \StartSummary{#1}{}#2\StopSummary
+ \resetlayer[main]
+ \setlayer[temp]{\foundbox{Summary}\CurrentSummary}
+ \setlayer[temp]{\foundbox{Subtext}\CurrentSummary}
+ \definereference[thispage][page(\CurrentSummary)]
+ \stopstandardmakeup}
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\TitlePage{August 2000}{Something Very Important}
+
+\StartSummary{Alpha}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\StartSummary{Beta and Gamma}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\StartSummary{Delta}
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\StartSummary{Epsilon}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\StartSummary{Zeta, Eta and Theta}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\StartSummary{Omega}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopSummary
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-26.tex b/tex/context/modules/common/s-pre-26.tex
new file mode 100644
index 000000000..7c1dec5f8
--- /dev/null
+++ b/tex/context/modules/common/s-pre-26.tex
@@ -0,0 +1,255 @@
+%D \module
+%D [ file=s-pre-26,
+%D version=2001.02.18,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 26,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D modes: reverse
+
+%D This is a nice and simple style, written in februari
+%D 2001. It uses a square papersize, derived from \type {S4}.
+%D Because this style is meant to be used with Zapf
+%D Chancery, I dedicate this style to Volker Schaa, a fan of
+%D Zapf.
+
+\setuppapersize
+ [S44][S44]
+
+\startmode[asintended]
+ \definetypeface[zaphy][cg][calligraphy][chancery]
+ \setupbodyfont[zaphy,cg,12pt]
+\stopmode
+
+\startnotmode[asintended]
+ \setupbodyfont[13pt]
+\stopnotmode
+
+%D We use the whole page.
+
+\setuplayout
+ [backspace=0pt,
+ topspace=0pt,
+ header=0pt,
+ footer=0pt,
+ bottom=0pt,
+ width=middle,
+ height=middle]
+
+%D We will be very tolerant in alignment.
+
+\setuptolerance
+ [verytolerant,stretch]
+
+%D Of course use navigation, but we hide the in this case
+%D ugly reverse video hyper spot.
+
+\setupinteraction
+ [state=start,
+ color=white,
+ contrastcolor=white,
+ style=\underbar,
+ click=no]
+
+%D This style looks best in a dark room, full screen.
+
+\setupinteractionscreen
+ [option=max]
+
+%D We use colors and remap a couple of standard colors.
+
+\setupcolors
+ [state=start]
+
+\definecolor[white] [s=.8]
+\definecolor[red] [r=.7]
+\definecolor[green] [g=.7]
+\definecolor[blue] [b=.7]
+\definecolor[yellow][r=.7,g=.7]
+
+\definecolor [PageColor][black]
+
+%D These colors will cyclic be assigned to \type
+%D {TextColor}.
+
+\definecolor [TextColor 0][white]
+\definecolor [TextColor 1][red]
+\definecolor [TextColor 2][green]
+\definecolor [TextColor 3][blue]
+\definecolor [TextColor 4][yellow]
+
+\definecolor [TextColor] [TextColor 0]
+
+%D We will collect everything in a layer.
+
+\definelayer
+ [main]
+ [state=repeat]
+
+%D We have quite some overlays.
+
+\defineoverlay [page] [\reuseMPgraphic{page}]
+\defineoverlay [text] [\useMPgraphic{text}]
+\defineoverlay [next] [\overlaybutton{nextpage}]
+\defineoverlay [prev] [\overlaybutton{previouspage}]
+\defineoverlay [main] [\composedlayer{main}]
+
+%D These end up as paper, page and text backgrounds. We need
+%D to locate the foreground, otherwise hyperlinks will not
+%D work.
+
+\setupbackgrounds % otherwise in acrobat 5 rounding error
+ [paper] % and one pixel white line
+ [backgroundcolor=Pagecolor,
+ background=page]
+
+\setupbackgrounds
+ [page]
+ [background={page,prev,foreground,main}]
+
+\setupbackgrounds
+ [text]
+ [background=next,
+ backgroundoffset=-10pt]
+
+%D This means that clicking on the center brings you to the
+%D next page, while clicking on teh page frame brings you one
+%D page back.
+
+%D As usual, the graphics are handled by \METAPOST:
+
+\startuseMPgraphic{text}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := (.7+uniformdeviate.3)*\MPcolor{TextColor} ;
+ p := p enlarged -1.25pt ;
+ filldraw p withcolor c ;
+ draw p withpen pencircle scaled 2.5pt withcolor .75c ;
+\stopuseMPgraphic
+
+\startreusableMPgraphic{page}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := \MPcolor{PageColor} ;
+ filldraw p enlarged 5pt withcolor c ; % bleeding
+\stopreusableMPgraphic
+
+%D The text is typeset in a framed text. We cycle trough the
+%D colors by means of a counter. This counter also determines
+%D the positioning on the main layer. The width is slightly
+%D random.
+
+\newcounter\KindOfTopic % and cycle through corners
+\newdimen \TopicWidth % with randomized widths
+
+\defineframedtext
+ [TopicText]
+ [frame=off,
+ offset=10pt,
+ style=bold,
+ width=\TopicWidth,
+ background=text,
+ before=,
+ after=,
+ align=normal]
+
+\def\BeforeTopic
+ {\ifcase\KindOfTopic\relax
+ \TopicWidth=.7\textwidth
+ \definecolor[CharColor][black]
+ \else
+ \getrandomdimen\TopicWidth{.55\textwidth}{.7\textwidth}
+ \definecolor[CharColor][white]
+ \fi
+ \doifmode{reverse}
+ {\setupframedtexts[TopicText][foregroundcolor=CharColor]}
+ \definecolor[TextColor][TextColor \KindOfTopic]
+ \ifcase\KindOfTopic\relax
+ \setuplayer[main][x=.5\textwidth,y=.5\textheight,location=c] \or
+ \setuplayer[main][x=0pt, y=0pt, location=rb] \or
+ \setuplayer[main][x=\textwidth, y=0pt, location=lb] \or
+ \setuplayer[main][x=\textwidth, y=\textheight, location=lt] \or
+ \setuplayer[main][x=0pt, y=\textheight, location=rt] \fi}
+
+\def\AfterTopic
+ {\ifnum\KindOfTopic=4
+ \gdef\KindOfTopic{1}
+ \else
+ \doglobal\increment\KindOfTopic
+ \fi}
+
+\def\StartTopic
+ {\BeforeTopic
+ \startstandardmakeup
+ \setlayer[main] \bgroup \startTopicText[none]
+ }%\setupwhitespace[big]} % generates an empty line
+
+\def\StopTopic
+ {\stopTopicText \egroup
+ \stopstandardmakeup
+ \AfterTopic}
+
+%D The title and colofon page are centered on the page.
+
+\def\StartNopic
+ {\doglobal\newcounter\KindOfTopic % centered at the page
+ \StartTopic
+ \bfd\setupinterlinespace
+ \setupinteraction[color=,contrastcolor=]%
+ \def\\{\blank\bfb\setupinterlinespace\def\\{\blank}}%
+ \raggedcenter\ignorespaces}
+
+\def\StopNopic
+ {\StopTopic}
+
+\let\StartTitlePage\StartNopic \let\StartColofonPage\StartNopic
+\let\StopTitlePage \StopNopic \let\StopColofonPage \StopNopic
+
+\def\TitlePage #1{\StartTitlePage #1\StopTitlePage}
+\def\ColofonPage#1{\StartColofonPage#1\StopColofonPage}
+
+%D We provide a minimum of title commands.
+
+\definehead
+ [Title]
+ [title]
+
+\definehead
+ [Subject]
+ [subject]
+
+\setuphead
+ [Title]
+ [style=\bfb,
+ page=,
+ before=,
+ after=\blank]
+
+\setuphead
+ [Subject]
+ [style=\bfa,
+ before=\blank,
+ after=\blank]
+
+\doifnotmode{demo}{\endinput}
+
+\def\Sample #1 {\input #1 \par \rightaligned{--- #1 ---}}
+
+\starttext
+
+\StartNopic The \ConTeXt\ Test Quotes \\ \currentdate \StopNopic
+
+\StartTopic \Sample tufte \StopTopic
+\StartTopic \Sample knuth \StopTopic
+\StartTopic \Sample zapf \StopTopic
+\StartTopic \Sample douglas \StopTopic
+\StartTopic \Sample stork \StopTopic
+\StartTopic \Sample materie \StopTopic
+
+\StartNopic There Will Be Some More \StopNopic
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-27.tex b/tex/context/modules/common/s-pre-27.tex
new file mode 100644
index 000000000..2e201e8df
--- /dev/null
+++ b/tex/context/modules/common/s-pre-27.tex
@@ -0,0 +1,181 @@
+%D \module
+%D [ file=s-pre-27,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 27,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize
+ [S6][S6]
+
+% \setupbodyfont[ppl]
+
+\definetypeface[main][rm][casual][informal][default]
+\loadmapfile[original-micropress-informal.map]
+
+\setupbodyfont[main,10pt]
+
+\setuplayout
+ [footerdistance=20pt,
+ footer=40pt,
+ %footer=24pt,
+ %bottomdistance=10pt,
+ %bottom=12pt,
+ header=0pt,
+ backspace=20pt,
+ topspace=20pt,
+ width=middle,
+ height=fit]
+
+% \def\MainTitle#1{\setupfootertexts[\hfill#1]}
+% \def\SubTitle #1{\setupbottomtexts[\hfill#1]}
+%
+% \MainTitle{a dull talk held at \currentdate}
+% \SubTitle {welcome to whatever}
+%
+% \setupbottom
+% [style=\ssbf,
+% color=white]
+%
+% \setupfooter
+% [style=\ssbfb,
+% color=white]
+
+\setupfooter
+ [strut=no,
+ style=\bfb,
+ color=white]
+
+\setupinteraction
+ [state=start]
+
+\setupinteractionscreen
+ [option=max]
+
+\definecolor[white] [s=.8]
+\definecolor[red] [r=.7]
+\definecolor[green] [g=.7]
+\definecolor[blue] [b=.7]
+\definecolor[yellow][r=.7,g=.7]
+
+\setupcolors
+ [state=start]
+
+\defineoverlay [page] [\reuseMPgraphic{page}]
+\defineoverlay [text] [\useMPgraphic {text}]
+\defineoverlay [continue] [\overlaybutton {forward}]
+
+\setupbackgrounds
+ [page]
+ [background={page,continue}]
+
+\definecolor [PageColor] [red]
+\definecolor [TextColor] [yellow]
+
+\defineframedtext
+ [TopicPage]
+
+\defineframedtext
+ [TopicText]
+
+\setupframedtexts
+ [TopicPage]
+ [width=\textwidth,
+ height=\textheight,
+ offset=overlay]
+
+\setupframedtexts
+ [TopicText]
+ [offset=10pt,
+ style=bold, % hm
+ width=\TopicWidth,
+ background=text,
+ align=normal]
+
+\setupframedtexts
+ [TopicPage,TopicText]
+ [frame=off,
+ depthcorrection=off,
+ before=,
+ after=]
+
+\newbox \TopicBox
+\newcounter \KindOfTopic
+\newdimen \TopicWidth
+
+\def\KindOfTopic{1}
+
+\def\StartTopic
+ {\getrandomdimen\TopicWidth{.5\textwidth}{.7\textwidth}
+ \ifcase\KindOfTopic\or
+ \setupframedtexts [TopicPage] [align={right,high}] \or
+ \setupframedtexts [TopicPage] [align={left,high}] \or
+ \setupframedtexts [TopicPage] [align={left,low}] \or
+ \setupframedtexts [TopicPage] [align={right,low}] \fi
+ \setbox\scratchbox=\vbox \bgroup \dontcomplain
+ \noindent \startTopicPage [none]
+ \noindent \startTopicText [none]
+ \setuptolerance [verytolerant,stretch]}
+
+\def\StopTopic%
+ {\stopTopicText
+ \stopTopicPage
+ \egroup
+ \global\setbox\TopicBox=\vbox
+ {\startoverlay
+ {\box\TopicBox} {\box\scratchbox}
+ \stopoverlay}
+ \copy\TopicBox
+ \ifnum\KindOfTopic=4
+ \def\KindOfTopic{1}
+ \else
+ \increment\KindOfTopic
+ \fi
+ \page}
+
+\startuseMPgraphic{text}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := (.7+uniformdeviate.3)*\MPcolor{TextColor} ;
+ p := p enlarged -1.25pt ;
+ fill p withcolor c ;
+ draw p withpen pencircle scaled 2.5pt withcolor .75c ;
+\stopuseMPgraphic
+
+\startreusableMPgraphic{page}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := \MPcolor{PageColor} ;
+ fill p withcolor c ;
+ draw p withpen pencircle scaled 2.5pt withcolor c ;
+\stopreusableMPgraphic
+
+\def\StartNopic#1\StopNopic
+ {\setupfootertexts
+ [\vbox to \footerheight
+ {\vfill
+ \raggedleft
+ \def\\{\endgraf\tx\setstrut\strut}
+ \setstrut\strut\ignorespaces#1\unskip\endgraf\removedepth}]
+ \null \page}
+
+\def\TitlePage#1%
+ {\StartNopic#1\StopNopic}
+
+\setuphead[title] [style=\bfc,after=\blank]
+\setuphead[subject][style=\bfa,before=\blank]
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\TitlePage
+ {a dull talk held at \currentdate\\welcome to whatever}
+
+\dorecurse{10}{\StartTopic \input tufte \StopTopic}
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-50.tex b/tex/context/modules/common/s-pre-50.tex
new file mode 100644
index 000000000..ff3e48631
--- /dev/null
+++ b/tex/context/modules/common/s-pre-50.tex
@@ -0,0 +1,101 @@
+%D \module
+%D [ file=s-pre-50,
+%D version=2003.01.26,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 50,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D When my mailbox started to overflow with messages about
+%D problems with the presentation step mechanism, I looked up
+%D old presentaton, hacked a bit and cooked up an alternative
+%D that is less dependent on \PDF\ trickery.
+%D
+%D Consider it a cheap trick and prelude to a couple of new
+%D presentation styles. (At the time of writing this, I
+%D still have some 10 of those styles to clean up and
+%D document.) You can give it a try:
+%D
+%D \starttyping
+%D texexec --pdf --mode=demo s-pre-50
+%D \stoptyping
+
+% Basic definitions.
+
+\defineframedtext
+ [horizontal]
+ [width=\textwidth,
+ frame=off,
+ strut=no,
+ height=fit,
+ align={right,lohi},
+ before=,
+ after=]
+
+\definecollector
+ [contribution]
+ [state=repeat,
+ corner={left,bottom},
+ location={right,bottom}]
+
+%D An example of tuning:
+
+\startmode[demo]
+
+ \setupcollector
+ [contribution]
+ [voffset=-.25\bodyfontsize]
+
+ \setupframedtexts
+ [horizontal]
+ [background=color,
+ backgroundcolor=darkgray,
+ foregroundcolor=white]
+
+\stopmode
+
+%D Structure and trick.
+
+\def\StartSteps
+ {\doifnotmode{mkiv}{\checkutilities}}
+
+\def\StopSteps
+ {\resetcollector[contribution]}
+
+\long\def\StartStep#1\StopStep
+ {\setcollector
+ [contribution]
+ {\starthorizontal[none]#1\stophorizontal}
+ \flushcollector[contribution]
+ \page}
+
+%D Trick. Nowadays we can use streams.
+
+\installoutputroutine\FlushStep
+ {\StartStep\unvbox\normalpagebox\StopStep}
+
+%D Demo.
+
+\doifnotmode{demo}{\endinput}
+
+\setupcolors[state=start] \setuppapersize[S6][S6] \setuplayout[middle]
+
+\starttext
+
+\StartSteps
+
+ \title[whow]{How Much?} \FlushStep
+ \item More \FlushStep
+ \item And More \FlushStep
+ \item And Even More \FlushStep
+
+ \StartStep And So On \StopStep
+
+\StopSteps
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-61.tex b/tex/context/modules/common/s-pre-61.tex
new file mode 100644
index 000000000..48b9d09a0
--- /dev/null
+++ b/tex/context/modules/common/s-pre-61.tex
@@ -0,0 +1,275 @@
+%D \module
+%D [ file=s-pre-61,
+%D version=2004.03.15,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 61,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Optima
+
+\usemodule[pre-60]
+
+\doifmodeelse {mkiv} {
+ \usetypescriptfile[ghz]
+ \definetypeface[mainface][ss][sans][optima-nova][default]
+} {
+ \usetypescriptfile[type-ghz]
+ \definetypeface[mainface][ss][sans][optima-nova][default][encoding=\defaultencoding]
+}
+
+\setupbodyfont[mainface,ss,18pt]
+\setupinterlinespace[line=3.25ex]
+
+\setuppapersize
+ [S6][S6]
+
+% \setuppapersize
+% [SW][SW]
+
+\setuplayout
+ [topspace=10pt,
+ header=30pt,
+ headerdistance=20pt,
+ height=middle,
+ footerdistance=20pt,
+ footer=0pt,
+ bottomdistance=20pt,
+ bottom=20pt,
+ bottomspace=50pt,
+ backspace=30pt,
+ width=middle]
+
+\setupinteraction
+ [state=start,
+ click=off,
+ menu=on,
+ style=,
+ color=interactioncolor,
+ contrastcolor=interactioncolor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupinteractionmenu
+ [bottom]
+ [color=maincolor,
+ contrastcolor=maincolor,
+ style=\tfa, % acceptable
+ left=\hfill,
+ middle=,
+ right=,
+ height=\bottomheight,
+ width=2\bottomheight,
+ offset=overlay,
+ frame=off]
+
+\startinteractionmenu[bottom]
+ \but [firstpage] \symbol[firstpage] \\
+ \but [previouspage] \symbol[previouspage] \\
+ \but [InvokeStepper] \StartBusy\symbol[PauseRendering]\StopBusy \\
+ \but [nextpage] \symbol[nextpage] \\
+ \but [lastpage] \symbol[lastpage] \\
+ \but [CloseDocument] \symbol[CloseDocument] \\
+\stopinteractionmenu
+
+% maybe in colo-sjk : \setupcolor[sjk]
+
+\definecolor [dark] [s=.4]
+\definecolor [bright] [s=.9]
+
+\definecolor [red] [r=.4,g=.2,b=.2]
+\definecolor [green] [r=.2,g=.4,b=.2]
+\definecolor [blue] [r=.2,g=.2,b=.4]
+
+\definecolor [cyan] [r=.2,g=.4,b=.4]
+\definecolor [magenta][r=.4,g=.2,b=.4]
+\definecolor [yellow] [r=.4,g=.4,b=.2]
+
+\definecolor [pagecolor] [dark]
+\definecolor [maincolor] [bright]
+\definecolor [textcolor] [red]
+
+\definecolor [interactioncolor] [r=.8,g=.8,b=.6]
+
+\setupcolors
+ [state=start,
+ textcolor=maincolor]
+
+\setupbackgrounds
+ [page]
+ [background=page,
+ backgroundcolor=textcolor]
+
+\setupbackgrounds
+ [text]% [text]
+ [background={comments,text,invoke}]
+
+\definelayer
+ [text]
+ [width=\textwidth,
+ height=\textheight]
+
+\defineoverlay
+ [comments]
+ [{\setlayer[text][preset=middle]{\placecomments}}]
+
+\defineoverlay[page][\uniqueMPgraphic{page-\ifcase\realpageno\or one\else plus\fi}]
+
+\startuniqueMPgraphic{page-one}
+ StartPage ;
+ fill Page
+ enlarged 4pt
+ withcolor \MPcolor{pagecolor} ;
+ fill Field[Text][Text]
+ enlarged 10pt
+% topenlarged (HeaderHeight+HeaderDistance)
+ leftenlarged (BackSpace+4pt)
+ rightenlarged (CutSpace +4pt)
+ withcolor OverlayColor ;
+ StopPage ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{page-plus}
+ StartPage ;
+ fill Page
+ enlarged 4pt
+ withcolor \MPcolor{pagecolor} ;
+ fill Field[Text][Text]
+ enlarged 10pt
+ leftenlarged (BackSpace+4pt)
+ rightenlarged (CutSpace+4pt)
+ withcolor OverlayColor ;
+ StopPage ;
+\stopuniqueMPgraphic
+
+% this needs to be sorted out !
+
+\appendtoks
+ \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold}
+ \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold}
+ \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold}
+ \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold}
+\to \everystarttext
+
+\appendtoks
+ \NormalizeFontHeight \HeadFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold}
+ \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {2.0\headerheight} {SansBold}
+ \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {1.5\headerheight} {SansBold}
+ \NormalizeFontHeight \SubSubTitleFont {\setstrut\strut\quad} {1.0\headerheight} {SansBold}
+\to \everystoptext
+
+\setuphead
+ [chapter]
+ [placehead=empty,
+ after={\blank[medium]},
+ color=maincolor,
+ placenumber=no,
+ style=\HeadFont]
+
+\setupheadertexts
+ [\doiftextelse{\currentheadnumber}{\placeheadtext[Topic]}{\placeheadtext[Nopic]}]
+ []
+
+\setuppagenumbering
+ [location=]
+
+\definesymbol
+ [emdash]
+ [\emdash]
+
+\setupitemize
+ [each]
+ [loose,serried,joinedup,broad]
+ [symbol=emdash]
+
+\setupalign
+ [broad,right]
+
+\def\doTitlePage#1#2#3%
+ {\startstandardmakeup[headerstate=high]
+ \def\\{\def\\{\endgraf\quad\quad}\endgraf\quad\ignorespaces#2}%
+ #1\setstrut\setupinterlinespace\vfil#3\vfil\vfil
+ \stopstandardmakeup}
+
+\def\TitlePage {\doTitlePage\TitleFont\relax}
+\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont}
+
+\definehead[Topic][chapter]
+\definehead[Nopic][title]
+
+\def\Topics#1%
+ {\Nopic[topics]{#1}
+ \startcolumns
+ \placelist[Topic]
+ \stopcolumns}
+
+\setuplist
+ [Topic]
+ [alternative=f,
+ color=maincolor,
+ contrastcolor=maincolor,
+ criterium=all]
+
+\defineoverlay[topics][\overlaybutton{topics}]
+
+\setupbackgrounds
+ [bottom] [text]
+ [background=topics]
+
+\continueifinputfile{s-pre-61.tex}
+
+\starttext
+
+\TitlePage{Stepwise\\Refinement}
+
+\Topics{Topics}
+
+\Topic{Female Artists}
+
+\StartSteps
+
+\startitemize
+\item Fiona Apple \FlushStep
+\item Tori Amos \FlushStep
+\item Kate Bush \FlushStep
+\item Heather Nova \FlushStep
+\item Alanis Morissette \FlushStep
+\item Suzanne Vega \FlushStep
+\stopitemize
+
+\StopSteps
+
+\Topic{Male Composers}
+
+\StartSteps
+
+\startitemize
+\item John Adams \FlushStep
+\item Steve Reich \FlushStep
+\item Louis Andriessen \FlushStep
+\item Olivier Messiaen \FlushStep
+\stopitemize
+
+\StopSteps
+
+\Topic{And Some More}
+
+\StartSteps
+
+\startitemize
+\item Mark Hollis \FlushStep
+\item Roger Waters \FlushStep
+\item David Gilmore \FlushStep
+\item Peter Gabriel \FlushStep
+\item Randy Newman \FlushStep
+\stopitemize
+
+\StopSteps
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-62.tex b/tex/context/modules/common/s-pre-62.tex
new file mode 100644
index 000000000..a1a405c23
--- /dev/null
+++ b/tex/context/modules/common/s-pre-62.tex
@@ -0,0 +1,224 @@
+%D \module
+%D [ file=s-pre-62,
+%D version=2005.03.04,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 62,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Melior
+
+\usemodule[pre-60]
+
+\usetypescriptfile
+ [type-ghz]
+
+\doifmodeelse {mkiv} {
+
+ \definetypeface[mainface][rm][serif][melior] [default]
+ \definetypeface[mainface][tt][mono] [modern] [default][rscale=1.05]
+ \definetypeface[mainface][ss][serif][melior] [default]
+ \definetypeface[mainface][mm][math] [palatino][default][rscale=0.95]
+
+} {
+
+ \definetypeface[mainface][rm][serif][melior] [default][encoding=texnansi]
+ \definetypeface[mainface][tt][mono] [modern] [default][encoding=texnansi,rscale=1.05]
+ \definetypeface[mainface][ss][serif][melior] [default][encoding=texnansi]
+ \definetypeface[mainface][mm][math] [palatino][default][encoding=texnansi,rscale=0.95]
+
+}
+
+\setupbodyfont
+ [mainface,14.4pt]
+
+\setuppapersize
+ [S6][S6]
+
+\setvariables[layout][dx=0,dy=1,nx=2,ny=2,step=64]
+
+\definemeasure[layoutwd][\dimexpr\paperwidth /\getvariable{layout}{step}\relax]
+\definemeasure[layoutht][\dimexpr\paperheight/\getvariable{layout}{step}\relax]
+
+\setuplayout
+ [ width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt,
+ margin=0pt,
+ backspace=5\measure{layoutwd},
+ topspace=5\measure{layoutht}]
+
+\definelayout
+ [step]
+ [ backspace=\numexpr2+ \getvariable{layout}{dx}\relax\measure{layoutwd},
+ cutspace=\numexpr3+\getvariable{layout}{nx}-\getvariable{layout}{dx}\relax\measure{layoutwd},
+ topspace=\numexpr2+ \getvariable{layout}{dy}\relax\measure{layoutht},
+ bottomspace=\numexpr3+\getvariable{layout}{ny}-\getvariable{layout}{dy}\relax\measure{layoutht}]
+
+\definecolor[layout:left] [t=.5,a=1,b=1]
+\definecolor[layout:right] [t=.5,a=1,r=1]
+\definecolor[layout:top] [t=.5,a=1,g=1]
+\definecolor[layout:bottom][t=.5,a=1,y=1]
+\definecolor[layout:page] [s=.75]
+
+\definehspace[menu][\measure{layoutwd}]
+
+\setupinteraction
+ [state=start,
+ click=off,
+ style=,
+ color=interactioncolor,
+ contrastcolor=interactioncolor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupbuttons
+ [color=maincolor,
+ contrastcolor=maincolor,
+ style=\tf, % acceptable
+ height=2\measure{layoutht},
+ width=2\measure{layoutwd},
+ offset=overlay,
+ frame=off]
+
+\definecolor[interactioncolor][darkgray]
+\definecolor[maincolor] [lightgray]
+
+\setuptexttexts
+ []
+ [\vbox to \textheight{\vfill\hfill\setups{menu:content}}]
+
+\startsetups menu:content
+
+ \button{\symbol[firstpage]}[firstpage]
+ \hspace[menu]
+ \button{\symbol[previouspage]}[previouspage]
+ \hspace[menu]
+ \button{\StartBusy\symbol[PauseRendering]\StopBusy}[InvokeStepper]
+ \hspace[menu]
+ \button{\symbol[nextpage]}[nextpage]
+ \hspace[menu]
+ \button{\symbol[lastpage]}[lastpage]
+ \hspace[menu]
+ \button{\symbol[CloseDocument]}[CloseDocument]
+
+\stopsetups
+
+\startuseMPgraphic{page}{step}
+ StartPage ;
+ numeric dx, dy ; dx := PaperWidth/\MPvar{step} ; dy := PaperHeight/\MPvar{step} ;
+ fill Page withcolor .5white ;
+ fill
+ ulcorner Page -- urcorner Page --
+ urcorner Page shifted (0,-TopSpace+dy) -- ulcorner Page shifted (0,-TopSpace+dy) -- cycle
+ withcolor \MPcolor{layout:top} ;
+ fill
+ llcorner Page -- lrcorner Page --
+ lrcorner Page shifted (0,BottomSpace-dy) -- llcorner Page shifted (0,BottomSpace-dy) -- cycle
+ withcolor \MPcolor{layout:bottom} ;
+ fill
+ ulcorner Page -- llcorner Page --
+ llcorner Page shifted (BackSpace-dx,0) -- ulcorner Page shifted (BackSpace-dx,0) -- cycle
+ withcolor \MPcolor{layout:left} ;
+ fill
+ urcorner Page -- lrcorner Page --
+ lrcorner Page shifted (-CutSpace+dx,0) -- urcorner Page shifted (-CutSpace+dx,0) -- cycle
+ withcolor \MPcolor{layout:right} ;
+ fill Field[Text][Text] enlarged (dx,dy) withcolor white ;
+ fill Field[Text][Text] enlarged (dx,dy) withcolor \MPcolor{layout:page} ;
+ StopPage ;
+\stopuseMPgraphic
+
+\defineoverlay[page][\useMPgraphic{page}{step=\getvariable{layout}{step}}]
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\setupcolors
+ [state=start]
+
+\startsetups nextstep
+ % pagebreak handlers are grouped, so we need to set global
+ \ifnum\getvariable{layout}{dx}=\getvariable{layout}{nx}\relax
+ \ifnum\getvariable{layout}{dy}=\getvariable{layout}{ny}\relax
+ \setxvariables[layout][dy=1]
+ \else
+ \setxvariables[layout][dy=\the\numexpr\getvariable{layout}{dy}+1\relax]
+ \fi
+ \setxvariables[layout][dx=1]
+ \else
+ \setxvariables[layout][dx=\the\numexpr\getvariable{layout}{dx}+1\relax]
+ \fi
+ % global anyway
+ \setuplayout[step]
+\stopsetups
+
+\definefontsynonym[MainTitleFont][SerifBold]
+
+\definefont[ChapterTitleFont][MainTitleFont sa 2]
+
+\appendtoks
+ \NormalizeFontHeight \TitleFont {\setstrut\strut\quad} {4\lineheight} {MainTitleFont}
+ \NormalizeFontHeight \SubTitleFont {\setstrut\strut\quad} {3\lineheight} {MainTitleFont}
+ \NormalizeFontHeight \ChapterNumberFont {XVI} {4\lineheight} {MainTitleFont}
+\to \everystarttext
+
+\setupsection
+ [section-2]
+ [bodypartconversion=Romannumerals]
+
+\installpagebreakhandler {step} {\setups{nextstep}}
+
+\definepagebreak[chapter][yes,step]
+
+\setuphead
+ [chapter]
+ [page=chapter,
+ command=\MyChapterCommand]
+
+\definehead[Topic][chapter]
+\definehead[Nopic][title]
+
+\setuphead[chapter,Topic,Nopic]
+ [numberstyle=\ChapterNumberFont,
+ textstyle=\ChapterTitleFont,
+ numbercolor=lightgray,
+ textcolor=darkgray]
+
+\def\MyChapterCommand#1#2%
+ {\hbox \bgroup % we need to nil the strut added by the headplacement
+ \setupframed[frame=off,lines=4,offset=overlay]%
+ \rlap{\hskip2\lineheight\framed{\setnostrut#1}}\framed{#2}%
+ \egroup}
+
+\setupitemize
+ [each]
+ [R,broad]
+ [stopper=,
+ color=lightgray]
+
+\def\doTitlePage#1#2#3%
+ {\startstandardmakeup[headerstate=high,textstate=stop]
+ \setupalign[middle]
+ \def\\{\def\\{\endgraf}\endgraf\vfil\ignorespaces#2}%
+ \startcolor[darkgray]
+ #1\setstrut\setupinterlinespace\vfil#3\vfil
+ \stopcolor
+ \stopstandardmakeup}
+
+\def\TitlePage {\doTitlePage\TitleFont\relax}
+\def\SubTitlePage{\doTitlePage\TitleFont\SubTitleFont}
+
+\long\def\StartTitlePage #1\StopTitlePage {\TitlePage {#1}}
+\long\def\StartSubTitlePage#1\StopSubTitlePage{\SubTitlePage{#1}}
+
+\endinput
+
diff --git a/tex/context/modules/common/s-pre-63.tex b/tex/context/modules/common/s-pre-63.tex
new file mode 100644
index 000000000..974c67a5f
--- /dev/null
+++ b/tex/context/modules/common/s-pre-63.tex
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=s-pre-63,
+%D version=2006.05.11,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 63,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+this module is under reconstruction
+
+\endinput
+
+\usemodule[pre-61,streams]
+
+\definemeasure[textgap] [\dimexpr24pt\relax]
+
+\definemeasure[leftwidth] [\dimexpr.25\textwidth-.5\measure{textgap}\relax]
+\definemeasure[rightwidth][\dimexpr.75\textwidth-.5\measure{textgap}\relax]
+
+\definestreamlayer[left] [width=\measure{leftwidth}]
+\definestreamlayer[right][width=\measure{rightwidth}]
+
+\setupbodyfont[12pt]
+
+\definefont[LeftFont][Normal sa 3]
+
+\setupheader[style=\tfc,before=\vss,after=\vss]
+
+\startsetups streamlayer:left:settings
+ \hsize\measure{leftwidth}
+ \LeftFont
+ \setupinterlinespace
+\stopsetups
+
+\startsetups streamlayer:right:settings
+ \hsize\measure{rightwidth}
+\stopsetups
+
+\definecombination[both][distance=\measure{textgap},location=top]
+
+\startsetups place:both
+ \startcombination[both]
+ {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {}
+ {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {}
+ \stopcombination
+\stopsetups
+
+\def\StartPage {\page \StartLocalSteps}
+\def\StopPage {\StopLocalSteps \page}
+
+\def\StartLeft {\startstreamlayer[left]}
+\def\StartRight{\startstreamlayer[right]}
+
+\def\StopLeft {\stopstreamlayer}
+\def\StopRight {\stopstreamlayer}
+
+\def\StartPair {}
+\def\StopPair {\setups[place:both]}
+
+% \doifnotmode {demo} {\endinput}
+
+\setupbodyfont[8pt] \definefont[BigFont][Normal sa 4]
+
+\starttext
+
+\StartPage
+ \StartPair \StartLeft ZAPF \StopLeft \StartRight \input zapf \StopRight \StopPair
+ \StartPair \StartLeft DAVIS \StopLeft \StartRight \input davis \StopRight \StopPair
+ \StartPair \StartLeft WARD \StopLeft \StartRight \input ward \StopRight \StopPair
+\StopPage
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-64.tex b/tex/context/modules/common/s-pre-64.tex
new file mode 100644
index 000000000..ef4889bbb
--- /dev/null
+++ b/tex/context/modules/common/s-pre-64.tex
@@ -0,0 +1,208 @@
+%D \module
+%D [ file=s-pre-64,
+%D version=2006.05.11,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 64,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% To be documented, used in 2007
+
+\usemodule[s][pre-60]
+
+\newcounter\shapesynctag
+\newdimen\slantedshapedimen
+\newdimen\slantedshapestep
+\newdimen\slantedshapeleftskip
+\newdimen\slantedshapeoffset
+\newdimen\slantedshapeextra
+
+\positioningtrue
+
+\def\AdaptShape
+ {\doglobal\increment\shapesynctag
+ \getnoflines\textheight
+ \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax
+ \leftskip\slantedshapeleftskip
+ \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax
+ \advance\scratchdimen\slantedshapeextra
+ \getnoflines\scratchdimen
+ \slantedshapedimen \noflines \slantedshapestep
+ \scratchtoks\emptytoks
+ \dorecurse{30}
+ {\appendetoks
+ \the\dimexpr-\slantedshapedimen+\slantedshapeoffset \relax\space
+ \the\dimexpr \hsize-2\slantedshapeoffset\relax\space
+ \to\scratchtoks
+ \advance\slantedshapedimen \slantedshapestep}%
+ \parshape 30 \the\scratchtoks
+ \strut\xypos\shapesynctag}
+
+\def\AdaptShapeX
+ {\doglobal\increment\shapesynctag
+ \getnoflines\textheight
+ \slantedshapestep\dimexpr\slantedshapeleftskip/\noflines\relax
+ \leftskip\slantedshapeleftskip
+ \scratchdimen\dimexpr\MPy{text:\MPp\shapesynctag}+\MPh{text:\MPp\shapesynctag}-\topskip-\MPy\shapesynctag\relax
+ \advance\scratchdimen\slantedshapeextra
+ \getnoflines\scratchdimen
+ \slantedshapedimen \noflines \slantedshapestep
+ \scratchtoks\emptytoks
+ \dorecurse{30}
+ {\appendetoks
+ \the\dimexpr-\slantedshapedimen+\slantedshapeoffset +5cm \relax\space
+ \the\dimexpr \hsize-2\slantedshapeoffset\relax\space
+ \to\scratchtoks
+ \advance\slantedshapedimen \slantedshapestep}%
+ \parshape 30 \the\scratchtoks
+ \strut\xypos\shapesynctag}
+
+\setuppapersize[S6][S6]
+
+\setupinteraction
+ [state=start,
+ click=no]
+
+\setupinteractionscreen
+ [option=max]
+
+\setuplayout
+ [backspace=12pt,
+ topspace=24pt,
+ height=middle,
+ width=middle,
+ header=0pt,
+ footer=0pt]
+
+\definecolor[maincolor][b=.5]
+\definecolor[somecolor][g=.5]
+\definecolor[morecolor][r=.5]
+
+\setupcolors
+ [textcolor=maincolor,
+ state=start]
+
+\setupbackgrounds
+ [text]% [text]
+ [background={base,text,invoke}]
+
+\definelayer
+ [text]
+ [width=\textwidth,
+ height=\textheight]
+
+\definelayer
+ [base]
+ [width=\textwidth,
+ height=\textheight]
+
+\definetype [epet] [style=,color=morecolor]
+\setuptype [style=,color=somecolor]
+
+\slantedshapeleftskip150pt
+\slantedshapeoffset12pt
+\slantedshapeextra10pt
+
+\startreusableMPgraphic{page}
+ StartPage ;
+ fill Page withcolor \MPcolor{maincolor} ;
+ path p ; p := Field[Text][Text] enlarged 6pt ;
+ p :=
+ llcorner p shifted (0,-12pt) --
+ lrcorner p shifted (-150pt,0) --
+ urcorner p shifted (0,12pt) --
+ ulcorner p shifted (150pt,0) --
+ cycle ;
+ fill p
+ withcolor .9white ;
+ StopPage ;
+\stopreusableMPgraphic
+
+\defineoverlay[page][\reuseMPgraphic{page}]
+\setupbackgrounds[page][background=page]
+
+\setupalign[flushleft]
+
+\def\StartItem
+ {\blank[line]
+ \begingroup
+ \EveryPar {\AdaptShape}} % beware: \ABBREV aan begin gaat fout
+
+\def\StopItem
+ {\endgraf
+ \endgroup
+ \blank[line]}
+
+\def\StartType
+ {\blank[halfline]
+ \begingroup
+ \EveryPar {\AdaptShape}
+ \dontleavehmode \quad}
+
+\def\StopType
+ {\endgraf
+ \endgroup
+ \blank[halfline]}
+
+\def\Title#1%
+ {\page
+ \setlayer
+ [text]
+ [preset=lefttop,
+ rotation=90]
+ {\color[white]{\scale[height=24pt]{\strut#1}}}}
+
+\def\SetBanner#1%
+ {\setuplayer[base][state=repeat]
+ \setlayer[base][preset=rightbottom]{\color[white]{\scale[height=9pt]{\strut#1}}}}
+
+\let\TitleFont\relax
+
+\startmode[atpragma]
+ \definefontfeature[default][method=node,script=latn,language=dflt,liga=yes,onum=yes,kern=yes]
+ \definefont[TitleFont][palatinosanscom-bold*default at 48pt]
+ \definefont[MainTextFont][palatinosanscom-regular*default at 12pt] \setupinterlinespace[line=15pt]
+ \appendtoks
+ \MainTextFont % hack, as we define a bodyfont at that point (better have a proper typeface)
+ \to \everystarttext
+\stopmode
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\usemodule[abr-01]
+
+\SetBanner{tug 2007 san diego}
+
+\Title {hans hagen}
+
+\startstandardmakeup \TitleFont \setupinterlinespace[line=3ex] \vfill
+
+\StartItem \dontleavehmode \quad {\morecolor zapfino, a} \StopItem
+\StartItem \dontleavehmode \quad {\morecolor torture test} \StopItem
+\StartItem \dontleavehmode \quad {\morecolor for luatex} \StopItem
+
+\vfill \stopstandardmakeup
+
+\Title{loading fonts}
+
+\StartSteps
+
+\StartItem the \OPENTYPE\ font reader is borrowed from \FONTFORGE\ \FlushStep \StopItem
+\StartItem once it was ready, we could look into such a font \FlushStep \StopItem
+\StartItem it tooks while to figure out the format due to rather fuzzy specs \FlushStep \StopItem
+\StartItem it took us even more time to find out that the loader was flawed \FlushStep \StopItem
+\StartItem one reason was that fonts themselves may have bugs or be incomplete \FlushStep \StopItem
+\StartItem then we changed to \FONTFORGE\ version 2 \FlushStep \StopItem
+\StartItem this made the missing pieces surface in more complex feature handling \FlushStep \StopItem
+\StartItem while implementing features the new table format was cleaned up \FlushStep \StopItem
+
+\StopSteps
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-66.tex b/tex/context/modules/common/s-pre-66.tex
new file mode 100644
index 000000000..3e89e4a7e
--- /dev/null
+++ b/tex/context/modules/common/s-pre-66.tex
@@ -0,0 +1,161 @@
+%D \module
+%D [ file=s-pre-66,
+%D version=2009.02.24,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 66,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Cambria (made in the aftermath of testing \OPENTYPE\ math).
+
+% \enablemode[paper]
+
+\usemodule[pre-60]
+\usemodule[abr-01]
+
+\definepapersize
+ [wide]
+ [width=960pt,
+ height=600pt]
+
+\setuppapersize
+ [wide]
+ [wide]
+
+\setuplayout
+ [topspace=20pt,
+ bottomspace=20pt,
+ header=0pt,
+ footer=0pt,
+ backspace=20pt,
+ height=middle,
+ rightmargin=0pt,
+ rightedge=\dimexpr220pt-40pt\relax,
+ rightedgedistance=40pt,
+ leftedge=0pt,
+ leftmargin=0pt,
+ cutspace=220pt,
+ width=\dimexpr960pt-40pt-220pt\relax]
+
+\definebodyfontenvironment
+ [20pt]
+
+\definefontfeature[default][default][mode=node,script=latn]
+
+\usetypescript
+ [cambria]
+
+\setupbodyfont
+ [cambria,20pt] \bf
+
+\setupwhitespace
+ [big]
+
+\setupcolors
+ [state=start]
+
+\definecolor[pagecolor][s=.25]
+\definecolor[edgecolor][b=.50,g=.75,r=.75]
+
+\setupinteraction
+ [state=start,
+ click=no,
+ color=,
+ contrastcolor=]
+
+\defineoverlay[pagegraphic][\reuseMPgraphic{pagegraphic}]
+
+\startuseMPgraphic{pagegraphic}
+ StartPage ;
+ fill Page enlarged 10pt withcolor \MPcolor{pagecolor} ;
+ fill Page enlarged 10pt leftenlarged (CutSpace - bbwidth(Page) - 10pt) withcolor \MPcolor{edgecolor} ;
+ % fill Field[Text][RightEdge] withcolor green ;
+ % fill Field[Text][Text] withcolor yellow ;
+ StopPage ;
+\stopuseMPgraphic
+
+\setupbackgrounds
+ [page]
+ [background=pagegraphic]
+
+\setupbackgrounds
+ [text]
+ [rightedge]
+ [background=edge]
+
+\definelayer
+ [edge]
+ [width=\rightedgewidth,
+ state=repeat]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ color=edgecolor]
+
+\setupcolors
+ [textcolor=edgecolor]
+
+\newcounter\MyCounter
+
+\def\StartRemark#1%
+ {\doglobal\increment\MyCounter % hm, we could use the autoref (todo in cont-xp)
+ \title[topic:\MyCounter]{#1}
+ \setlayer[edge][preset=middletop,y=\thelayerheight{edge}]{\strut\color[pagecolor]{\bf\goto{#1}[topic:\MyCounter]}}
+ \StartSteps}
+
+\def\StopRemark
+ {\StopSteps
+ \page}
+
+\def\StartRemark#1%
+ {\doglobal\increment\MyCounter % hm, we could use the autoref (todo in cont-xp)
+ \title[topic:\MyCounter]{#1}
+ \StartSteps
+ \def\StopRemark
+ {\StopSteps
+ \page
+ \setlayer[edge][preset=middletop,y=\thelayerheight{edge}]{\strut\color[pagecolor]{\bf\goto{#1}[topic:\MyCounter]}}}}
+
+\def\StartTitlePage
+ {\startstandardmakeup[top=\vss,bottom=\vss\vss]
+ \definedfont[Bold sa 4]
+ \raggedcenter
+ \setupinterlinespace
+ \baselineskip=1\baselineskip plus 1fil minus 1fil\relax}
+
+\def\StopTitlePage
+ {\stopstandardmakeup}
+
+\doifnotmode{demo} {\endinput}
+
+\starttext
+
+\StartTitlePage x\\y\\z \StopTitlePage
+
+\StartRemark{a}
+ a \FlushStep
+ a \FlushStep
+\StopRemark
+
+\StartRemark{b}
+ b \FlushStep
+ b \FlushStep
+ b \FlushStep
+\StopRemark
+
+\StartRemark{c}
+ c \FlushStep
+ c \FlushStep
+ c \FlushStep
+ c \FlushStep
+\StopRemark
+
+\stoptext
+
+
diff --git a/tex/context/modules/common/s-pre-67.tex b/tex/context/modules/common/s-pre-67.tex
new file mode 100644
index 000000000..84ea1a66c
--- /dev/null
+++ b/tex/context/modules/common/s-pre-67.tex
@@ -0,0 +1,155 @@
+% todo: version of placement that also takes the sync node
+
+\usemodule[s][abr-02]
+\usemodule[s][pre-60]
+
+\definecolor[red:fullcolor] [r=1]
+\definecolor[red:lightcolor] [r=.5]
+\definecolor[red:darkcolor] [r=.375]
+
+\definecolor[green:fullcolor] [g=1]
+\definecolor[green:lightcolor] [g=.5]
+\definecolor[green:darkcolor] [g=.375]
+
+\definecolor[blue:fullcolor] [b=1]
+\definecolor[blue:lightcolor] [b=.5]
+\definecolor[blue:darkcolor] [b=.375]
+
+\definepalet[red-scheme] [fullcolor=red:fullcolor, lightcolor=red:lightcolor, darkcolor=red:darkcolor]
+\definepalet[green-scheme][fullcolor=green:fullcolor,lightcolor=green:lightcolor,darkcolor=green:darkcolor]
+\definepalet[blue-scheme] [fullcolor=blue:fullcolor, lightcolor=blue:lightcolor, darkcolor=blue:darkcolor]
+
+\setuppalet[red-scheme]
+
+\setupcolors
+ [textcolor=darkcolor]
+
+\setupinteraction
+ [color=darkcolor,
+ contrastcolor=darkcolor]
+
+\startuseMPgraphic{bullet}
+ path b, p ;
+ p := fullsquare scaled .5LineHeight ;
+ b := boundingbox p ;
+ p := p rotatedaround(center p, 45) ;
+ p := p shifted (0,-.125StrutDepth) ;
+ fill p withcolor \MPcolor{lightcolor} ;
+ setbounds currentpicture to b ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{bar}
+ path b, p ;
+ p := fullsquare scaled .25LineHeight ;
+ b := boundingbox p ;
+ p := p rotatedaround(center p, 45) ;
+ p := p shifted (0,+.25StrutDepth) ;
+ fill p withcolor \MPcolor{lightcolor} ;
+ setbounds currentpicture to b ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{page}
+ StartPage ;
+ fill Page enlarged 5mm withcolor .1[white,\MPcolor{fullcolor}] ;
+ interim linecap := butt ;
+ numeric h ; h := bbheight(Page)/4 ;
+ numeric w ; w := bbwidth(Page)/4 ;
+ h := h randomized(h) ;
+ w := w randomized(w) ;
+ draw
+ ulcorner Page shifted (0,-h) -- ulcorner Page -- ulcorner Page shifted (w,0)
+ withpen pensquare scaled .5cm
+ withcolor \MPcolor{lightcolor} ;
+ numeric h ; h := bbheight(Page)/4 ;
+ numeric w ; w := bbwidth(Page)/4 ;
+ h := h randomized(h) ;
+ w := w randomized(w) ;
+ draw
+ lrcorner Page shifted (0,h) -- lrcorner Page -- lrcorner Page shifted (-w,0)
+ withpen pensquare scaled .5cm
+ withcolor \MPcolor{lightcolor} ;
+ setbounds currentpicture to Page ;
+ StopPage ;
+\stopuseMPgraphic
+
+\defineoverlay[page][\useMPgraphic{page}]
+
+\definesymbol[1][\reuseMPgraphic{bullet}]
+\definesymbol[2][\reuseMPgraphic{bar}]
+
+\setupitemgroup[itemize][2][width=1em]
+
+\setupinteraction
+ [state=start,
+ click=no]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt,
+ backspace=1cm,
+% topspace=1cm]
+ topspace=.5cm]
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\setuphead
+ [chapter]
+ [command=\MyCommand,
+ before=,
+ after={\blank[disable]},
+ color=lightcolor,
+ style=\bfc]
+
+\definelayer
+ [title]
+ [width=\paperwidth,
+ height=\paperheight]
+
+\setupbackgrounds
+ [page]
+ [background={page,title}]
+
+\setupwhitespace
+ [big]
+
+\unexpanded\def\MyCommand#1#2%
+ {\setlayer[title][preset=rightbottom,x=.75cm,y=.5cm]{#2}}
+
+\def\titlepage#1#2%
+ {\startstandardmakeup
+ \definefont[LargeFont][Normal at 100pt]
+ \setlayerframed
+ [title]
+ [preset=lefttop,x=1cm,y=.25cm]
+ [align=flushleft,foregroundstyle=\LargeFont,offset=0pt,foregroundcolor=lightcolor,frame=off]
+ {#1}
+ \definefont[SmallFont][Normal at 50pt]
+ \setlayerframed
+ [title]
+ [preset=rightbottom,x=1cm,y=.5cm]
+ [align=flushright,foregroundstyle=\SmallFont,offset=0pt,foregroundcolor=lightcolor,frame=off]
+ {#2}
+ \stopstandardmakeup}
+
+\let\Title\title
+\let\TitlePage\titlepage
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+ \chapter{Test}
+ \startitemize
+ \startitem test \stopitem
+ \startitem test \stopitem
+ \startitem test \stopitem
+ \stopitemize
+\stoptext
+
+\endinput
diff --git a/tex/context/modules/common/s-pre-68.tex b/tex/context/modules/common/s-pre-68.tex
new file mode 100644
index 000000000..3c04a87e1
--- /dev/null
+++ b/tex/context/modules/common/s-pre-68.tex
@@ -0,0 +1,150 @@
+%D \module
+%D [ file=s-pre-68,
+%D version=2009.08.28,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 68,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[pre-60,abr-02]
+
+% style
+
+\setuppapersize
+ [S66][S66]
+
+\setuplayout
+ [height=middle,
+ width=middle,
+ header=0pt,
+ footer=0pt,
+ backspace=2cm,
+ topspace=2cm]
+
+\setupinteraction
+ [state=start,
+ click=no]
+
+\definecolor[maincolor][r=.4]
+
+\startreusableMPgraphic{page}
+ StartPage ;
+ fill Page enlarged 5mm withcolor \MPcolor{maincolor} ;
+ StopPage ;
+\stopreusableMPgraphic
+
+\startreusableMPgraphic{next}
+ fill ultriangle scaled .15PaperWidth withcolor white ;
+\stopreusableMPgraphic
+
+\startreusableMPgraphic{last}
+ fill boundingbox(ultriangle scaled .15PaperWidth) withcolor white ;
+\stopreusableMPgraphic
+
+\startuniqueMPgraphic{bullit}
+ fill ultriangle scaled 2ExHeight withcolor white ;
+\stopuniqueMPgraphic
+
+\definelayer
+ [extra]
+ [width=\paperwidth,
+ height=\paperheight]
+
+\defineoverlay
+ [page]
+ [\reuseMPgraphic{page}]
+
+\setupbackgrounds
+ [page]
+ [background={page,extra}]
+
+\setupcolors
+ [state=start,
+ textcolor=white]
+
+\setuphead
+ [chapter]
+ [style=\bfc]
+
+\definehead[Title][title]
+
+\definesymbol[MyBullet][\uniqueMPgraphic{bullit}]
+
+\setupitemgroup[itemize][each][symbol=MyBullet]
+
+\usetypescript[cambria]
+\setupbodyfont[cambria,14.4pt]
+
+% interface
+
+\def\StartItems
+ {\begingroup
+ \StartSteps
+ \startitemize
+ \def\StartItems{\startitemize\def\StopItems{\stopitemize}}}
+
+\def\StopItems
+ {\FlushStep
+ \stopitemize
+ \NextPageSymbol
+ \StopSteps
+ \endgroup}
+
+\def\Item
+ {\def\Item{\FlushStep\item}
+ \item}
+
+\def\NextPageSymbol
+ {\setlayer
+ [extra]
+ [preset=rightbottom,offset=2mm]
+ {\ifnum\realpageno=\lastpage
+ \reuseMPgraphic{last}%
+ \else\ifnum\realpageno>1
+ \reuseMPgraphic{next}%
+ \fi\fi
+ \FlushStep}}
+
+\def\TitlePage#1#2%
+ {\startstandardmakeup[bottom=,top=]
+ \scale[width=\textwidth]{\framed[align=flushleft,foregroundstyle=\bf,frame=off]{#1}}
+ \vfilll
+ \hfill\scale[width=.5\textwidth]{\framed[align=flushright,foregroundstyle=\bf,frame=off]{#2}}
+ \stopstandardmakeup}
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\TitlePage{I'm running\\out of examples}{Hans Hagen\\Someplace, 2031}
+
+\Title{Alpha}
+
+\StartItems
+\Item one
+\Item two
+\Item three
+\StopItems
+
+\Title{Beta}
+
+\StartItems
+\Item four
+\Item five
+\Item six
+\StopItems
+
+\Title{Gamma}
+
+\StartItems
+\Item seven
+\Item eight
+\Item nine
+\StopItems
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-93.tex b/tex/context/modules/common/s-pre-93.tex
new file mode 100644
index 000000000..c36762f38
--- /dev/null
+++ b/tex/context/modules/common/s-pre-93.tex
@@ -0,0 +1,208 @@
+%D \module
+%D [ file=s-pre-20,
+%D version=2000.08.07,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 20,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setupbodyfont
+ [lbr,14.4pt]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=0cm,
+ backspace=0cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [state=start,
+ click=no,
+ display=new,
+ color=LineColor,
+ contrastcolor=LineColor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupsystem
+ [random=big] % once per hour
+
+\startreusableMPgraphic{page}
+ StartPage ;
+ filldraw Page withcolor \MPcolor{PageColor} ;
+ pickup pencircle scaled (.25cm+uniformdeviate.25cm) ;
+ for i=1 upto 200 :
+ drawdot
+ (uniformdeviate PaperWidth,uniformdeviate PaperHeight)
+ withcolor \MPcolor {LineColor} ;
+ endfor ;
+ StopPage ;
+\stopreusableMPgraphic
+
+\startuseMPgraphic{idea}
+ StartPage ;
+ path p ;
+ p := unitsquare xyscaled(\MPw{idea:\realfolio},\MPh{idea:\realfolio}) superellipsed .90 ;
+ p := p shifted \MPxy{idea:\realfolio} ;
+ draw p withpen pencircle scaled .500cm withcolor \MPcolor{PageColor} ;
+ fill p withcolor \MPcolor{\overlaycolor} ;
+ draw p withpen pencircle scaled .250cm withcolor \MPcolor{LineColor} ;
+ p := unitsquare xyscaled(\MPw{title:\realfolio},\MPh{title:\realfolio}) superellipsed .90 ;
+ p := p shifted \MPxy{title:\realfolio} ;
+ draw p withpen pencircle scaled .250cm withcolor \MPcolor{PageColor} ;
+ fill p withcolor \MPcolor{\overlaycolor} ;
+ draw p withpen pencircle scaled .125cm withcolor \MPcolor{LineColor} ;
+ StopPage ;
+\stopuseMPgraphic
+
+\definecolor[PageColor][s=.50]
+\definecolor[TextColor][s=.80]
+\definecolor[DoneColor][s=.65]
+\definecolor[LineColor][r=.7,g=.6,b=.5]
+
+\defineoverlay [idea] [\useMPgraphic {idea}]
+\defineoverlay [page] [\reuseMPgraphic{page}]
+
+\setupbackgrounds
+ [page]
+ [background={page,forward}]
+
+\defineoverlay[forward][\overlaybutton{forward}]
+
+% alternatief: buffer en ander regime, zodat lokale kleuren
+% kunnen worden genilled. Pos gebruiken om te positioneren.
+
+\definereference[thispage][page(\realfolio)]
+
+\newbox\firstideabox \setbox\firstideabox =\null
+\newbox\secondideabox \setbox\secondideabox=\null
+\newbox\thirdideabox \setbox\thirdideabox =\null
+
+\def\StartTopic% bottom title, top title
+ {\dodoublegroupempty\doStartTopic}
+
+\def\doStartTopic#1#2% the positions end up at each page -)
+ {\setbox\firstideabox=
+ \vbox to \makeupheight
+ \bgroup
+ \getrandomdimen\scratchdimen{.5cm}\makeupheight
+ \vskip 0cm plus \scratchdimen
+ \hbox to \makeupwidth
+ \bgroup
+ \getrandomdimen\scratchdimen{.5cm}\makeupwidth
+ \hskip 0cm plus \scratchdimen
+ \setbox\scratchbox=\hbox\bgroup\hpos{idea:\realfolio}
+ \bgroup
+ \getrandomdimen\hsize{.5\makeupwidth}{.7\makeupwidth}%
+ \framed
+ [offset=3ex,align=middle,strut=no,frame=off,
+ before=,after=]
+ \bgroup
+ \setupwhitespace[big]%
+ \doifsomething{#2}{\Title{#2}}%
+ \def\StopTopic{%
+ \egroup
+ \egroup
+ \egroup
+ \gotobox{\box\scratchbox}[thispage]%
+ \getrandomdimen\scratchdimen{.5cm}\makeupwidth
+ \hskip 0cm plus \scratchdimen
+ \egroup
+ \getrandomdimen\scratchdimen{.5cm}\makeupheight
+ \vskip 0cm plus \scratchdimen
+ \hbox to \makeupwidth
+ \bgroup
+ \hfill
+ \hpos{title:\realfolio}
+ {\button[offset=1.5ex,frame=off]{#1}[backward]}%
+ \getrandomdimen\scratchdimen{.5cm}{2.5cm}%
+ \hskip \scratchdimen
+ \egroup
+ \getrandomdimen\scratchdimen{.5cm}{1.5cm}
+ \vskip \scratchdimen
+ \egroup
+ \setbox\secondideabox=\vbox
+ {\framed
+ [offset=overlay,frame=off,background=idea,backgroundcolor=TextColor]
+ {\copy\firstideabox}}
+ \setbox\firstideabox=\vbox
+ {\framed
+ [offset=overlay,frame=off,background=idea,backgroundcolor=DoneColor]
+ {\LineColor\copy\firstideabox}}
+ \startstandardmakeup
+ \startoverlay
+ {\copy\thirdideabox }
+ {\copy\secondideabox}
+ \stopoverlay
+ \stopstandardmakeup
+ \setbox\thirdideabox=\vbox
+ {\startoverlay
+ {\copy\thirdideabox }
+ {\copy\firstideabox}
+ \stopoverlay}}}
+
+\long\def\TitlePage#1#2%
+ {\bgroup
+ \switchtobodyfont[32pt]
+ \StartTopic{#1}#2\StopTopic
+ \egroup}
+
+\def\Title#1{\midaligned{\bfb#1}\blank}
+
+\doifnotmode{demo}{\endinput}
+
+% \usemodule[pre-super] % super ellipse as well as superpositioned
+
+\starttext
+
+\TitlePage{August 2000}{Something Very Important}
+
+\StartTopic{Alpha}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\StartTopic{Beta and Gamma}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\StartTopic{Delta}
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\StartTopic{Epsilon}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\StartTopic{Zeta, Eta and Theta}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\StartTopic{Omega}
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+ A simple and not too long text just to show the idea.
+\StopTopic
+
+\stoptext
diff --git a/tex/context/modules/common/s-pre-96.tex b/tex/context/modules/common/s-pre-96.tex
new file mode 100644
index 000000000..2ad752007
--- /dev/null
+++ b/tex/context/modules/common/s-pre-96.tex
@@ -0,0 +1,188 @@
+%D \module
+%D [ file=s-pre-26,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 26,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize
+ [S44][S44]
+
+\definetypeface[main][rm][casual][informal][default]
+
+\setupbodyfont[main,13pt]
+
+\setuplayout
+ [backspace=0pt,
+ topspace=0pt,
+ header=0pt,
+ footer=0pt,
+ bottom=0pt,
+ width=middle,
+ height=fit]
+
+\setupbottom
+ [style=\ssbf,
+ color=white]
+
+\setupfooter
+ [style=\ssbfb,
+ color=white]
+
+\setupinteraction
+ [state=start,
+ click=no]
+
+\setupinteractionscreen
+ [option=max]
+
+\definecolor[white] [s=.8]
+\definecolor[red] [r=.7]
+\definecolor[green] [g=.7]
+\definecolor[blue] [b=.7]
+\definecolor[yellow][r=.7,g=.7]
+
+\setupcolors
+ [state=start]
+
+\defineoverlay [page] [\reuseMPgraphic{page}]
+\defineoverlay [text] [\useMPgraphic {text}]
+\defineoverlay [continue] [\overlaybutton {nextpage}]
+
+\setupbackgrounds % otherwise in acrobat 5 rounding error
+ [paper] % and one pixel white line
+ [background=page]
+
+\setupbackgrounds
+ [page]
+ [background={page,continue}]
+
+\definecolor [PageColor][black]
+
+\definecolor [TextColor 0][white]
+\definecolor [TextColor 1][red]
+\definecolor [TextColor 2][green]
+\definecolor [TextColor 3][blue]
+\definecolor [TextColor 4][yellow]
+
+\definecolor [TextColor] [TextColor 0]
+
+\defineframedtext
+ [TopicPage]
+
+\defineframedtext
+ [TopicText]
+
+\setupframedtexts
+ [TopicPage]
+ [width=\textwidth,
+ height=\textheight,
+ offset=overlay]
+
+\setupframedtexts
+ [TopicText]
+ [offset=10pt,
+ style=bold,
+ width=\TopicWidth,
+ background=text,
+ align=normal]
+
+\setupframedtexts
+ [TopicPage,TopicText]
+ [frame=off,
+ depthcorrection=off,
+ before=,
+ after=]
+
+\newbox \TopicBox % we stack old pages
+\newcounter\KindOfTopic % and cycle through corners
+\newdimen \TopicWidth % with randomized widths
+
+\setupinteraction
+ [color=lightgray,
+ contrastcolor=lightgray,
+ style=]
+
+\def\StartTopic
+ {\definecolor[TextColor][TextColor \KindOfTopic]
+ \ifcase\KindOfTopic\relax
+ \TopicWidth=.7\textwidth
+ \else
+ \getrandomdimen\TopicWidth{.55\textwidth}{.7\textwidth}
+ \fi
+ \ifcase\KindOfTopic\relax
+ \setupframedtexts [TopicPage] [align={middle,lohi}] \or
+ \setupframedtexts [TopicPage] [align={right,high}] \or
+ \setupframedtexts [TopicPage] [align={left,high}] \or
+ \setupframedtexts [TopicPage] [align={left,low}] \or
+ \setupframedtexts [TopicPage] [align={right,low}] \fi
+ \setbox\scratchbox=\vbox \bgroup \dontcomplain
+ \noindent \startTopicPage [none]
+ \noindent \startTopicText [none] }
+
+\def\StopTopic%
+ {\stopTopicText
+ \stopTopicPage
+ \egroup
+ \global\setbox\TopicBox=\vbox
+ {\startoverlay
+ {\box\TopicBox} {\box\scratchbox}
+ \stopoverlay}
+ \copy\TopicBox
+ \ifnum\KindOfTopic=4
+ \def\KindOfTopic{1}
+ \else
+ \increment\KindOfTopic
+ \fi
+ \getrandomdimen\TopicWidth{.55\textwidth}{.7\textwidth}
+ \page}
+
+\startuseMPgraphic{text}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := (.7+uniformdeviate.3)*\MPcolor{TextColor} ;
+ p := p enlarged -1.25pt ;
+ filldraw p withcolor c ;
+ draw p withpen pencircle scaled 2.5pt withcolor .75c ;
+\stopuseMPgraphic
+
+\startreusableMPgraphic{page}
+ path p ; p := unitsquare xyscaled (OverlayWidth,OverlayHeight) ;
+ color c ; c := \MPcolor{PageColor} ;
+ filldraw p enlarged 5pt withcolor c ; % bleeding
+ draw p withpen pencircle scaled 2.5pt withcolor c ;
+\stopreusableMPgraphic
+
+\def\StartNopic
+ {\def\KindOfTopic{0} % centered at the page
+ \StartTopic
+ \bfd\setupinterlinespace
+ \def\\{\blank\bfb\setupinterlinespace}
+ \raggedcenter}
+
+\def\StopNopic
+ {\StopTopic}
+
+\def\TitlePage#1%
+ {\StartNopic#1\StopNopic}
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\StartNopic
+ a dull talk \\ \currentdate
+\StopNopic
+
+\dorecurse{10}{\StartTopic \input tufte \StopTopic}
+
+\StartNopic
+ that's it \\ goodbye
+\StopNopic
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-arabtex.mkii b/tex/context/modules/mkii/m-arabtex.mkii
new file mode 100644
index 000000000..dea1cae25
--- /dev/null
+++ b/tex/context/modules/mkii/m-arabtex.mkii
@@ -0,0 +1,450 @@
+%D \module
+%D [ file=m-arabtex, % was font-arb,
+%D version=2003.02.22, % 1999.11.06,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Arabic,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% I still need to hook in some features into the setup
+% macro. I also have to (re)define farsi etc. in ways
+% similar to arab, so that we have dedicated environments.
+%
+% keywords needed: vocalize transscribe
+%
+% \startarabic[option=vocalize] % or vocalize=yes
+% ......
+% \stoparabic
+
+\writestatus{loading}{ConTeXt Font Macros / ArabTeX support}
+
+%D At the \NTG\ 10\high{th} anniversary meeting Klaus Lagally
+%D introduced the audience to arabic typesetting, and after
+%D that I knew that some day I really had to look into his
+%D generic package. And then, sort of simultaniously Maarten
+%D Wisse and Imran Ahsan Nyazee asked me if \CONTEXT\ could
+%D support \ARABTEX, a package that provides right to left
+%D typesetting of (several variants of) arab and hebrew.
+%D Having implemented support for chinese a few weeks before,
+%D I could not resist to build in support for arab and hebrew
+%D too. Writing support for languages that don't give me any
+%D cue on how to pronounce their script, is kind of special.
+
+%D This is a beta version, since I still have to take care of some
+%D macros that conflict with existing stuff.
+
+\unprotect
+
+\definesystemvariable{ARABTEX}
+
+\def\setupARABTEX
+ {\getparameters[\??ARABTEX]}
+
+\setupARABTEX
+ [\s!rscale=1.2,
+ \c!before=,
+ \c!after=,
+ \c!inner=\setarab,
+ \c!style=\setarabicfont\fontstylesuffix]
+
+%D A few (maybe too) simple hooks into the font mechanism. The
+%D hook into the language module is not yet done.
+
+% \unexpanded\def\setarabicfont#1% rscale
+% {\scratchdimen\@@ARABTEXrscale\bodyfontsize
+% \font\arbfont\truefontname{Arabic#1} at \currentfontscale\scratchdimen
+% \setx@skels
+% \newfonttrue
+% \arbfont}
+%
+% more modern
+%
+% \unexpanded\def\setarabicfont#1% rscale
+% {\definefont[arbfont][Arabic#1 sa \@@ARABTEXrscale]%
+% \setx@skels
+% \newfonttrue
+% \arbfont}
+%
+% more efficient
+
+\unexpanded\def\setarabicfont#1%
+ {\setx@skels
+ \newfonttrue
+ \definedfont[Arabic#1 sa \ARABTEXparameter\s!rscale]}
+
+%D Just to be compatible with Arab\TEX\ we define:
+
+\unexpanded\def\nash {\setarabicfont\s!Regular}
+\unexpanded\def\nashbf {\setarabicfont\s!Bold }
+\unexpanded\def\pnash {\setarabicfont\s!Regular}
+\unexpanded\def\pnashbf{\setarabicfont\s!Bold }
+\unexpanded\def\xnash {\setarabicfont\s!Regular}
+\unexpanded\def\xnashbf{\setarabicfont\s!Bold }
+
+%D The display arabic environment (will be an installable
+%D object) uses a few conditionals. Let's do it the
+%D \CONTEXT\ way and define an anvironment that we later can
+%D adapt.
+
+\newif\if@ignore
+\newif\if@endpe
+
+\def\setupARABTEXalternative[#1]%
+ {\dodoubleempty\getparameters[\??ARABTEX#1]}
+
+\def\defineARABTEXalternative
+ {\dodoubleempty\dodefineARABTEXalternative}
+
+\def\dodefineARABTEXalternative[#1][#2]%
+ {\iffirstargument % \startarab is defined but used already
+ \getparameters
+ [\??ARABTEX#1]
+ [\c!before=\@@ARABTEXbefore,
+ \c!after=\@@ARABTEXafter,
+ \c!inner=\@@ARABTEXinner,
+ \c!style=\@@ARABTEXstyle,
+ \s!rscale=\@@ARABTEXrscale,
+ #2]%
+ \setvalue {\e!start#1}{\displayARABTEXalternative{#1}}%
+ \unexpanded\setvalue{#1}{\inlineARABTEXalternative {#1}}%
+ \unexpanded\def\RL{\getvalue{#1}}%
+ \unexpanded\def\LR{\a@LR}%
+ \let\R=\RL
+ \let\L=\LR
+ \expandafter\all@wcmd\csname\e!stop#1\endcsname
+ \else
+ \defineARABTEXalternative[arabic]%
+ \fi}
+
+\def\initializeARABTEXinternals
+ {\ARABTEXparameter\c!inner
+ \the\everyARABTEXpreset}
+
+\newtoks \everyARABTEXpreset
+
+\let\currentARABTEXalternative\empty
+
+\def\ARABTEXparameter#1%
+ {\csname\??ARABTEX\currentARABTEXalternative#1\endcsname}
+
+\def\inlineARABTEXalternative#1#2%
+ {\bgroup
+ \edef\currentARABTEXalternative{#1}%
+ \initializeARABTEXinternals
+ \a@RL{#2}%
+ \egroup}
+
+\def\displayARABTEXalternative#1%
+ {\dodoubleempty\dostartARABTEXalternative[#1]}
+
+\def\dostartARABTEXalternative[#1][#2]%
+ {\begingroup
+ \edef\currentARABTEXalternative{#1}%
+ \getparameters[\??ARABTEX\currentARABTEXalternative][#2]%
+ \ifnum1<0\ARABTEXparameter\c!n\relax
+ \startcolumns
+ \else
+ \ARABTEXparameter\c!before
+ \fi
+ \initializeARABTEXinternals
+ \initializeARABTEXend
+ \arabtext
+ \initializeARABTEXalternative}
+
+\def\initializeARABTEXalternative
+ {\ARABTEXparameter\c!style}
+
+\def\initializeARABTEXend% \CONTEXT\ does use \end quite differently
+ {\long\def\end##1%
+ {\endarabtext
+ \ifnum1<0\ARABTEXparameter\c!n\relax
+ \stopcolumns
+ \else
+ \ARABTEXparameter\c!after
+ \fi
+ \endgroup}%
+ \let\a@l@end\end
+ \letvalue{\e!stop\currentARABTEXalternative}=\end
+ \long\def\end##1%
+ {\endarabtext
+ \endgroup
+ \if@ignore\global\@ignorefalse\expandafter\ignorespaces\fi}}
+
+%D Arabic verbatim.
+
+\def\typearab{\a@@verb}
+
+%D Some \LATEX\ macros.
+
+\def \makeatletter{\unprotect}
+\def \makeatother {\protect}
+\def \typeout {\writestatus{arabtex}}
+
+%D We have to save some macros.
+
+\let\ARABTEXversion=\empty
+
+\def\startloadingARABTEX% ugly hacks
+ {\catcode`!=12
+ \catcode`?=12
+ \pushmacro\output \let \output \scratchtoks
+ \pushmacro\LaTeX \let \LaTeX \undefined
+ \pushmacro\CJK \let \CJK \undefined
+% \pushmacro\peek@token \let \peek@token \undefined
+% \pushmacro\edmacloaded \let \edmacloaded \undefined
+ \pushmacro\year \let \year \normalyear
+ \pushmacro\month \let \month \normalmonth
+ \pushmacro\day \let \day \normalday
+ \pushmacro\input \def \input ##1 {\normalinput ##1 }
+ \pushmacro\linewidth
+ \pushmacro\datum \def\datum {\toks0}
+ \pushmacro\version \def\version {\toks2}
+ \pushmacro\theversion \let\theversion \ARABTEXversion
+ \pushmacro\emphasize
+ \pushmacro\cap}
+
+\def\stoploadingARABTEX
+ {\catcode`!=11
+ \catcode`?=11
+ \popmacro\cap
+ \popmacro\emphasize
+ \popmacro\theversion
+ \popmacro\version
+ \popmacro\datum
+ \popmacro\linewidth
+ \popmacro\input
+ \popmacro\day
+ \popmacro\month
+ \popmacro\year
+% \popmacro\edmacloaded
+% \popmacro\peek@token
+ \popmacro\CJK
+ \popmacro\LaTeX
+ \popmacro\output}
+
+%D We save some macros:
+
+\startloadingARABTEX
+
+%D When loading \ARABTEX\ we have to set back the~! and~?.
+
+\input arabtex.sty
+
+%D Since \ARABTEX\ has its own \type {\cap}, we save the
+%D new meaning. We also redefine some \PLAIN\ macros, which
+%D happen to have a different meaning in \LATEX.
+
+\let\ARABTEXversion\theversion
+\let\ARABTEXcap \cap
+
+\appendtoks
+ \let\cap\ARABTEXcap
+\to \everyARABTEXpreset
+
+\def\ARABTEXsh@ft#1%
+ {\dimen@.00#1ex
+ \multiply\dimen@\slantperpoint
+ \kern-.0156\dimen@}
+
+\appendtoks
+ \let\sh@ft\ARABTEXsh@ft
+\to \everyARABTEXpreset
+
+\def\ARABTEXd#1%
+ {{\o@lign{\relax#1\crcr\hidewidth\sh@ft{10}%
+ .\hidewidth}}}
+
+\def\ARABTEXb#1%
+ {{\o@lign{\relax#1\crcr\hidewidth\sh@ft{29}%
+ \vbox to.2ex{\hbox{\char22}\vss}\hidewidth}}}
+
+\appendtoks
+ \let\b\ARABTEXb
+ \let\d\ARABTEXd
+\to \everyARABTEXpreset
+
+\def \ARABTEXbreakA {\hfill\break}
+\def \ARABTEXbreakB {\break}
+\edef\ARABTEXbar {\string|}
+\def \ARABTEXcomma {\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+
+\appendtoks
+ \let\\=\ARABTEXbreakA
+ \let\|=\ARABTEXbreakB
+ \let |=\ARABTEXbar
+ \let\,=\ARABTEXcomma
+\to \everyARABTEXpreset
+
+\let\ARABTEXprotect\relax
+
+\appendtoks
+ \let\protect\ARABTEXprotect
+\to \everyARABTEXpreset
+
+%D Now we can pop the saved macros.
+
+\stoploadingARABTEX
+
+%D Ah, we have to get rid of some \type {\protect} stuff but
+%D to permit testing we add it in the \CONTEXT\ way.
+
+% \bgroup
+% \catcode`\<=\@other
+% \unexpanded\gdef\a@ins
+% {\ifmmode
+% \expandafter<%
+% \else
+% \dontleavehmode \bgroup
+% \arab@codes \set@arabfont \@waslafalse \@wasfalse
+% \expandafter\arab@insert
+% \fi}
+% \unexpanded\gdef\<{\a@ins}
+% \catcode`\<=\active
+% \global\let<=\a@ins
+% \egroup
+%
+% cleaner:
+
+\defineactivecharacter < {\a@ins} \unexpanded\gdef\<{\a@ins}%
+
+\def\normal@a@ins
+ {\dontleavehmode % context prefers this instead of \leavevmode
+ \bgroup
+ \arab@codes
+ \set@arabfont
+ \@waslafalse
+ \@wasfalse
+ \arab@insert}
+
+\unexpanded\gdef\a@ins
+ {\mathortext<\normal@a@ins}
+
+%D We also need to register a few macros:
+
+\all@wcmd\initializeARABTEXalternative % no argument, internal command
+\all@wcmd\tx % no argument, small font
+\all@wcmd\txx % no argument, smaller font
+
+%D We also hook it into the presetter.
+
+\appendtoks
+ \let\normaltx \tx \def\tx {\normaltx \setarabicfont\fontstylesuffix}%
+ \let\normaltxx\txx\def\txx{\normaltxx\setarabicfont\fontstylesuffix}%
+\to \everyARABTEXpreset
+
+%D The main definitions are:
+
+\definefontsynonym [ArabicRegular] [xnsh14]
+\definefontsynonym [ArabicBold] [xnsh14bf]
+
+\defineARABTEXalternative
+ [arabic]
+ [\c!inner=\setarab,
+ \c!style=\setarabicfont\fontstylesuffix]
+
+\defineARABTEXalternative
+ [farsi]
+ [\c!inner=\setfarsi,
+ \c!style=\setarabicfont\fontstylesuffix]
+
+\defineARABTEXalternative
+ [urdu]
+ [\c!inner=\seturdu,
+ \c!style=\setarabicfont\fontstylesuffix]
+
+\defineARABTEXalternative
+ [maghribi]
+ [\c!inner=\setmaghribi,
+ \c!style=\setarabicfont\fontstylesuffix]
+
+%D Apart from such definitions, one can adapt the settings
+%D using \type {\setupARABTEXalternative}.
+%D
+%D A few years ago at the Holland Festivities, I attended {\em
+%D The Cave}, one of the most impressive combinations of music
+%D and video I know. This composition of Steve Reich (music)
+%D and .. (video) concentrates on the common grounds of arabs
+%D and jews: their ancestor Abram. Listening to the \CDROM's
+%D of {\em The Cave}, provided me the right ambiance for
+%D filling in the details of this module. In {\em The Cave},
+%D interviews, music, and |<|believe it or not|>| rhythmic
+%D typography are the cornerstones. Remembering those big
+%D screens, it strikes me that like music, \TEX\ too is a
+%D perfect instrument to cross cultural and linguistic
+%D borders. So, let's load Hebrew support as well:
+
+\unexpanded\def\sethebrewfont#1%
+ {\setx@skels
+ \newfonttrue
+ \definedfont[Hebrew#1 sa \ARABTEXparameter\s!rscale]}
+
+% \let \setheb \sethebrew
+
+\unexpanded\def\pheb {\sethebrewfont\s!Regular}
+\unexpanded\def\phebbf{\sethebrewfont\s!Bold}
+
+% \startloadingARABTEX
+
+% \ReadFile{hebtex.sty}
+% \ReadFile{apatch.sty}
+% \ReadFile{hepatch.sty}
+
+% \stoploadingARABTEX
+
+\definefontsynonym [HebrewRegular] [hclassic]
+\definefontsynonym [HebrewBold] [hcaption]
+
+\defineARABTEXalternative
+ [hebrew]
+ [\c!inner=\sethebrew,
+ \c!style=\sethebrewfont\fontstylesuffix]
+
+%D Now we're done:
+
+\protect \endinput
+
+% everyoutput : \charsubdefmax \arab@charsubdefmax
+
+% \defineconversion [abjad] [\abj@d]
+%
+% voetnoten verbatim lijsten indexen tabellen uitlijnen
+%
+% \v!hoofdstuk=al-fa.slu
+% \v!inhoud=al-mu.htawayAtu
+% \v!figuren=qA'imaTu al-.suwaru
+% \v!tabellen=qA'imaTu al-^gadAwilu
+% \v!grafieken=qA'imaTu al-rusUmu
+% \v!index=al-fihrisu
+% \v!bijlage=al-mul.haqu
+
+% \usemodule[arabtex]
+%
+% \usetypescript[postscript] \switchtotypeface[postscript]
+%
+% \setarab \novocalize
+%
+% \starttext
+%
+% \placecontent
+%
+% \section{\<mu.hammad>} % short arabic use \< .. >
+% \section{\<mu.hammad>} % short arabic use \< .. >
+%
+% \startarabic
+% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm
+%
+% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm
+% \stoparabic
+%
+% \section{\<al-maq.sad>}
+%
+% \startarabic
+% mu.hammad 'i_d q"aAm zay"d" + i_d yaqUm zyd + A_d zyd q"aAm
+% \stoparabic
+%
+% \stoptext
diff --git a/tex/context/modules/mkii/m-chart.mkii b/tex/context/modules/mkii/m-chart.mkii
new file mode 100644
index 000000000..8a5f480ee
--- /dev/null
+++ b/tex/context/modules/mkii/m-chart.mkii
@@ -0,0 +1,1315 @@
+%D \module
+%D [ file=m-chart,
+%D version=1998.10.10,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Flow Charts,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: \localpushmacro/\localpopmacro (dohandleflowchart etc)
+% todo: make mkiv variant
+% todo: use dimexpr/numspr
+
+% will be redone with layers and dimexpr or even better, by just using
+% textext .. a nice example of old code
+
+%D This is an experimental module. Pieces of code will be moved
+%D to other modules. More features are possible but will be
+%D interfaces later.
+%D
+%D When finished this module will be documented. The main macro
+%D is still a rather big one and there is some redundant and
+%D slow code that needs a clean up.
+
+% arrow, dash
+% crossing
+% \goto -> \normalgoto
+% class -> class:name (ref prefix)
+% c, automatisch geen overlap zoeken
+% eind eerder chart connecties
+% relateren aan korps
+% check op bestaan naam, bestaan shape
+% auto als extern figuur
+% subchart
+% pijlen
+% focus
+% ook nog \MPmessage
+% areapath -> krappe vlak
+% clippath -> gehele vlak
+%
+% offset : clip offset
+% breedte : breedte cel
+% hoogte : hoogte cel
+% dx : halve afstand in breedte (grid breedte = breedte + 2dx)
+% dy : halve afstand in hoogte (grid hoogte = hoogte + 2dy)
+% x : x offset (clipping)
+% y : y offset (clipping)
+% nx : minimaal aantal cellen horizontaal
+% ny : minimaal aantal cellen vertikaal
+%
+% shape none en geen equivalent maken
+%
+% kaderkleur achtergrondkleur
+% lijnkleur lijndikte
+% focus focuskaderkleur focusachtergrondkleur
+% richting
+%
+% focus koppelen aan kleur
+
+\unprotect
+
+\definesorting [flowchart] [flowcharts] [\v!none] % no access
+\setupsorting [flowchart] [\c!state=\v!stop] % off by default
+
+\def\@FLOW@{@FLOW@}
+\def\@FLOC@{@FLOC@}
+\def\@FLOX@{@FLOX@}
+
+\def\@@FLOW{@@FLOW}
+\def\@@FLOL{@@FLOL}
+\def\@@FLOS{@@FLOS}
+\def\@@FLOF{@@FLOF}
+\def\@@FLOT{@@FLOT}
+\def\@@FLOX{@@FLOX}
+
+\def\@@MPx {@@MPx}
+\def\@@MPy {@@MPy}
+
+\def\FLOWbufferprefix{flw-}
+
+\def\processFLOWbuffer#1{\getbuffer[\FLOWbufferprefix#1]}
+\def\typeFLOWbuffer #1{\typebuffer[\FLOWbufferprefix#1]}
+
+\def\setFLOWname#1#2% funny hack that makes sure that we get
+ {\bgroup % names that are acceptable for METAPOST
+ \lccode`0=`a\lccode`1=`b\lccode`2=`c\lccode`3=`d\lccode`4=`e%
+ \lccode`5=`f\lccode`6=`g\lccode`7=`h\lccode`8=`i\lccode`9=`j%
+ \lccode` =`\_\lccode`-=`\_\lccode`_=`\_%
+ \lowercase{\gdef#1{#2}}%
+ \egroup}
+
+% een gobble als default is sneller, en dan alleen setten als
+% nodig
+
+\def\resetFLOWcell
+ {% variables
+ \global\let\FLOWname \empty
+ \global\let\FLOWalign \empty
+ \global\let\FLOWshape \empty
+ \global\let\FLOWlocation \empty
+ \global\let\FLOWtext \empty
+ \global\let\FLOWhelp \empty
+ \global\let\FLOWdestination\empty
+ \global\let\FLOWoverlay \empty
+ \global\let\FLOWfocus \empty
+ \global\let\tFLOWlabel \empty
+ \global\let\bFLOWlabel \empty
+ \global\let\lFLOWlabel \empty
+ \global\let\rFLOWlabel \empty
+ \global\let\bcFLOWlabel \empty
+ \global\let\tcFLOWlabel \empty
+ \global\let\lcFLOWlabel \empty
+ \global\let\rcFLOWlabel \empty
+ \global\let\tFLOWexit \empty
+ \global\let\bFLOWexit \empty
+ \global\let\lFLOWexit \empty
+ \global\let\rFLOWexit \empty
+ % commands
+ \let\name \doFLOWname
+ \let\shape \doFLOWshape
+ \let\destination\doFLOWdestination
+ \let\location \doFLOWlocation
+ \let\focus \doFLOWfocus
+ \let\overlay \doFLOWoverlay
+ \let\figure \doFLOWfigure
+ \let\text \doFLOWtext
+ \let\comment \doFLOWcomment
+ \let\label \doFLOWlabel
+ \let\help \doFLOWhelp
+ \let\connection \doFLOWconnection
+ \let\exit \doFLOWexit
+ % convenience commands
+ \let\locate \doFLOWlocate
+ \let\connect \doFLOWconnect}
+
+\let\FLOWcell \s!unknown
+\let\FLOWshape \s!unknown
+\let\FLOWdestination\s!unknown
+\let\FLOWfocus \s!unknown
+\let\FLOWoverlay \empty
+\let\FLOWtext \empty
+
+\def\doFLOWname#1%
+ {\def\FLOWcell{#1}\setFLOWname\FLOWname{name_#1}\ignorespaces}
+
+\def\doFLOWshape#1%
+ {\gdef\FLOWshape{#1}\ignorespaces}
+
+\def\doFLOWdestination#1%
+ {\gdef\FLOWdestination{#1}\ignorespaces}
+
+\def\doFLOWlocation#1%
+ {\setFLOWlocation#1\end\ignorespaces}
+
+\def\doFLOWfocus#1%
+ {\gdef\FLOWfocus{#1}\ignorespaces}
+
+\def\doFLOWoverlay#1%
+ {\gdef\FLOWoverlay{#1}\ignorespaces}
+
+\def\doFLOWfigure#1%
+ {\defineoverlay[\s!dummy][\overlayfigure{#1}]%
+ \overlay\s!dummy}
+
+\def\doFLOWtext
+ {\dosingleempty\dodoFLOWtext}
+
+\def\dodoFLOWtext[#1]% % #2%
+ {\gdef\FLOWalign{#1}\gdef\FLOWtext}% {#2}}
+
+\def\doFLOWcomment[#1]#2%
+ {\ignorespaces\dogobblesingleempty}
+
+\def\doFLOWlabel[#1]#2% wordt dit gebruikt ?
+ {\setgvalue{#1FLOWlabel}{#2}\ignorespaces}
+
+\def\doFLOWhelp#1%
+ {\gdef\FLOWhelp{#1}\ignorespaces}
+
+\def\doFLOWconnection
+ {\dodoubleempty\dodoFLOWconnection}
+
+\def\dodoFLOWconnection[#1][#2]#3%
+ {\ignorespaces}
+
+\def\doFLOWconnect
+ {\connection}
+
+\def\doFLOWlocate
+ {\location}
+
+\def\doFLOWexit[#1]#2%
+ {\setgvalue{#1FLOWexit}{#2}\ignorespaces}
+
+\def\startFLOWchart
+ {\bgroup
+ \let\stopFLOWchart\egroup
+ \obeylines % lelijk, buffers nog eens fatsoeneren
+ \dodoubleempty\dostartFLOWchart}
+
+\def\dostartFLOWchart[#1][#2]%
+ {\preparenextFLOWchart{#1}{#2}%
+ \dostartbuffer[\FLOWbufferprefix\nofFLOWcharts][startFLOWchart][stopFLOWchart]}
+
+\def\defineFLOWchart%
+ {\dodoubleempty\dodefineFLOWchart}
+
+\long\def\dodefineFLOWchart[#1][#2]#3%
+ {\preparenextFLOWchart{#1}{#2}%
+ \setbuffer[\FLOWbufferprefix\nofFLOWcharts]#3\endbuffer}
+
+\def\preparenextFLOWchart#1#2%
+ {\doglobal\increment\nofFLOWcharts
+ \flowchart{#1}%
+ \setxvalue{\@FLOW@-#1}{\noexpand\dohandleflowchart[\nofFLOWcharts][#2]}}
+
+\def\setupFLOWcharts{\dodoubleargument\getparameters[\@@FLOW]}
+\def\setupFLOWlines {\dodoubleargument\getparameters[\@@FLOL]}
+\def\setupFLOWshapes{\dodoubleargument\getparameters[\@@FLOS]}
+\def\setupFLOWfocus {\dodoubleargument\getparameters[\@@FLOF]}
+\def\setupFLOWsets {\dodoubleargument\getparameters[\@@FLOX]}
+
+\setupFLOWcharts
+ [\c!option=,
+ \c!bodyfont=,
+ \c!dot=, % private option
+ \c!width=12\bodyfontsize,
+ \c!height=7\bodyfontsize,
+ \c!maxwidth=,
+ \c!maxheight=,
+ \c!offset=\v!standard, % == auto offset
+ \c!dx=2\bodyfontsize,
+ \c!dy=2\bodyfontsize,
+ \c!nx=0, % 1,
+ \c!ny=0, % 1,
+ \c!x=1,
+ \c!y=1,
+ \c!autofocus=,
+ \c!focus=,
+ \c!background=, % \v!color,
+ \c!backgroundcolor=\s!white,
+ \c!rulethickness=\linewidth,
+ \c!frame=\v!off,
+ \c!framecolor=]
+
+\setupFLOWlines
+ [\c!corner=\v!round,
+ \c!arrow=\v!yes,
+ \c!dash=\v!no,
+ \c!radius=.375\bodyfontsize, % 2.5\c!rulethickness
+ \c!color=FLOWlinecolor,
+ \c!rulethickness=.15\bodyfontsize, % 2pt,
+ \c!offset=\v!none]
+
+\setupFLOWshapes
+ [\c!default=action,
+ \c!framecolor=FLOWframecolor,
+ \c!background=\v!color,
+ \c!backgroundcolor=FLOWbackgroundcolor,
+ \c!backgroundscreen=\@@rsscreen,
+ \c!rulethickness=.15\bodyfontsize, % 2pt,
+ \c!offset=.5\bodyfontsize]
+
+\setupFLOWfocus
+ [\c!framecolor=FLOWfocuscolor,
+ \c!background=\@@FLOSbackground,
+ \c!backgroundcolor=\@@FLOSbackgroundcolor,
+ \c!backgroundscreen=\@@FLOSbackgroundscreen,
+ \c!rulethickness=\@@FLOSrulethickness,
+ \c!offset=\@@FLOSoffset]
+
+\definecolor [FLOWfocuscolor] [s=.2]
+\definecolor [FLOWlinecolor] [s=.5]
+\definecolor [FLOWframecolor] [s=.7]
+\definecolor [FLOWbackgroundcolor] [s=.9]
+
+\newcounter\includeFLOWx
+\newcounter\includeFLOWy
+
+\def\includeFLOWchart
+ {\dodoubleempty\doincludeFLOWchart}
+
+\def\doincludeFLOWchart[#1][#2]%
+ {\pushmacro\includeFLOWx
+ \pushmacro\includeFLOWy
+ \getparameters[FLOWi][x=1,y=1,#2]%
+ \increment(\includeFLOWx,0\FLOWix)\decrement\includeFLOWx
+ \increment(\includeFLOWy,0\FLOWiy)\decrement\includeFLOWy
+ \def\dodoincludeFLOWchart##1%
+ {\doifdefined{\@FLOW@-##1}
+ {\globalpushmacro\dohandleflowchart % was local
+ \gdef\dohandleflowchart[####1][####2]%
+ {\globalpopmacro\dohandleflowchart % was local
+ \resetFLOWlocation
+ \processFLOWbuffer{####1}}%
+ \getvalue{\@FLOW@-##1}}}%
+ \processcommalist[#1]\dodoincludeFLOWchart
+ \popmacro\includeFLOWx
+ \popmacro\includeFLOWy}
+
+\def\resetFLOWlocation
+ {\globallet\lastFLOWx\!!zerocount
+ \globallet\lastFLOWy\!!zerocount}
+
+\def\dosetFLOWlocation[#1#2]#3#4%
+ {\processaction
+ [#1#2]
+ [ +=>\scratchcounter\numexpr#4+ 1+#3\relax,
+ -=>\scratchcounter\numexpr#4- 1+#3\relax,
+ +#2=>\scratchcounter\numexpr#4+#2+#3\relax,
+ -#2=>\scratchcounter\numexpr#4-#2+#3\relax,
+ \s!default=>\scratchcounter\numexpr#4 +#3\relax,
+ \s!unknown=>\scratchcounter\numexpr0#1#2+#3\relax]%
+ \xdef#4{\the\scratchcounter}}
+
+\def\setFLOWlocation#1,#2\end
+ {\dosetFLOWlocation[#1\empty]\includeFLOWx\lastFLOWx
+ \dosetFLOWlocation[#2\empty]\includeFLOWy\lastFLOWy
+ \xdef\FLOWlocation{\lastFLOWx,\lastFLOWy}}
+
+\def\FLOWshapes
+ {node, action, procedure, product, decision, archive,
+ loop, wait, subprocedure, singledocument, multidocument,
+ sub procedure, single document, multi document, up, down,
+ left, right}
+
+\def\FLOWlines
+ {up, down, left, right}
+
+\def\FLOWsetconnect#1%
+ {\donefalse
+ \let\cFLOWfrom\empty
+ \let\cFLOWto\empty
+ \let\zFLOWfrom\!!zerocount
+ \let\zFLOWto\!!zerocount
+ \handletokens#1\with\doFLOWsetconnect
+ \ifx\cFLOWto\empty\let\cFLOWfrom\empty\fi}
+
+\def\doFLOWsetconnect#1%
+ {\ifx #1p%
+ \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi
+ \else\ifx#1+%
+ \ifdone\def\zFLOWto{+1}\else\def\zFLOWfrom{+1}\fi
+ \else\ifx#1n%
+ \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi
+ \else\ifx#1-%
+ \ifdone\def\zFLOWto{-1}\else\def\zFLOWfrom{-1}\fi
+ \else\ifdone
+ \edef\cFLOWto{\FLOWconnector#1}%
+ \else
+ \edef\cFLOWfrom{\FLOWconnector#1}%
+ \donetrue
+ \fi\fi\fi\fi\fi}
+
+\def\FLOWconnector#1%
+ {\if#1bbottom\else\if#1ttop\else\if#1lleft\else\if#1rright\fi\fi\fi\fi}
+
+\newif\ifFLOWscaling \FLOWscalingtrue
+
+\def\@@FLOW@@offset{\@@FLOWoffset}
+
+\def\getFLOWchart
+ {\dodoubleempty\dogetFLOWchart}
+
+\def\dogetFLOWchart[#1][#2]%
+ {\doifundefinedelse{\@FLOW@-#1}
+ {\writestatus{FLOW}{unknown chart #1}%
+ \framed
+ [\c!width=12\bodyfontsize,\c!height=8\bodyfontsize]
+ {\tttf [chart #1]}}
+ {\dodogetFLOWchart[#1][#2]}}
+
+\def\dodogetFLOWchart[#1][#2]% to be split a bit more
+ {\vbox\bgroup
+ \insidefloattrue
+ \forgetall
+ \dontcomplain
+ % \offinterlineskip % we now explicitly use \nointerlineskip later on
+ \def\dohandleflowchart[##1][##2]%
+ {\def\currentFLOWnumber{##1}%
+ \getparameters[\@@FLOW][##2]}%
+ \getvalue{\@FLOW@-#1}%
+ \getparameters[\@@FLOW][#2]% dubbelop ?
+ \doifsomething{\@@FLOWautofocus}
+ {\checkFLOWautofocus}%
+ %\message{AUTOSHAPE 3: (\@@FLOWx,\@@FLOWy)->(\@@FLOWnx,\@@FLOWny)}\wait
+ \global\let\FLOWwidth \@@FLOWnx
+ \global\let\FLOWheight\@@FLOWny
+ \let\startFLOWcell\startFLOWcellA
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber
+ \ifcase\@@FLOWnx\relax \let\@@FLOWnx\FLOWwidth \fi
+ \ifcase\@@FLOWny\relax \let\@@FLOWny\FLOWheight \fi
+ \doifnothing{\@@FLOWmaxwidth\@@FLOWmaxheight}{\FLOWscalingfalse}%
+ \ifFLOWscaling
+ \doifnothing{\@@FLOWmaxwidth }{\let\@@FLOWmaxwidth \maxdimen}%
+ \doifnothing{\@@FLOWmaxheight}{\let\@@FLOWmaxheight\maxdimen}%
+ \scratchcounter\bodyfontpoints
+ \doloop % NOG FONTSWITCH OM EX EN EM TE LATEN WERKEN
+ {\ifnum\scratchcounter>1 % NU DIMENSIONS IN TERMS OF BODYFONTSIZE
+ \bodyfontsize=\the\scratchcounter pt
+ \dimen0=\@@FLOWmaxwidth
+ \dimen2=\@@FLOWwidth
+ \dimen4=\@@FLOWdx
+ \advance\dimen2 2\dimen4
+ \dimen2=\@@FLOWnx\dimen2
+ \advance\dimen2 2\dimen4
+ \ifdim\dimen2>\dimen0
+ \advance\scratchcounter \minusone
+ \else
+ \dimen0=\@@FLOWmaxheight
+ \dimen2=\@@FLOWheight
+ \dimen4=\@@FLOWdy
+ \advance\dimen2 2\dimen4
+ \dimen2=\@@FLOWny\dimen2
+ \advance\dimen2 2\dimen4
+ \ifdim\dimen2>\dimen0
+ \advance\scratchcounter \minusone
+ \else
+ \exitloop
+ \fi
+ \fi
+ \else
+ \exitloop
+ \fi}%
+ \expanded{\switchtobodyfont[\the\scratchcounter pt]}%
+ \forgetall
+ % \offinterlineskip % needed ?
+ \else\ifx\@@FLOWbodyfont\empty\else
+ \expanded{\switchtobodyfont[\@@FLOWbodyfont]}% \expanded ?
+ \fi\fi
+ \global\let\FLOWcells\empty
+ \dimen0=\@@FLOWwidth
+ \edef\FLOWshapewidth{\the\dimen0}%
+ \dimen2=\@@FLOWdx
+ \advance\dimen0 2\dimen2
+ \edef\FLOWgridwidth{\the\dimen0}%
+ \dimen0=\@@FLOWheight
+ \edef\FLOWshapeheight{\the\dimen0}%
+ \dimen2=\@@FLOWdy
+ \advance\dimen0 2\dimen2
+ \edef\FLOWgridheight{\the\dimen0}%
+ \scratchdimen=\@@FLOSrulethickness
+ \edef\@@FLOSrulethickness{\the\scratchdimen}%
+ \scratchdimen=\@@FLOFrulethickness
+ \edef\@@FLOFrulethickness{\the\scratchdimen}%
+ \scratchdimen=\@@FLOLrulethickness
+ \edef\@@FLOLrulethickness{\the\scratchdimen}%
+ \ifdim\@@FLOLradius<2.5\scratchdimen
+ \scratchdimen=2.5\scratchdimen
+ \edef\@@FLOLradius{\the\scratchdimen}%
+ \ifdim\@@FLOLradius>\@@FLOWdx
+ \scratchdimen=\@@FLOWdx
+ \edef\@@FLOLradius{\the\scratchdimen}%
+ \fi
+ \ifdim\@@FLOLradius>\@@FLOWdy
+ \scratchdimen=\@@FLOWdy
+ \edef\@@FLOLradius{\the\scratchdimen}%
+ \fi
+ \else
+ \scratchdimen=\@@FLOLradius
+ \edef\@@FLOLradius{\the\scratchdimen}%
+ \fi
+ \processaction % magic 2.5
+ [\@@FLOWoffset]
+ [ \v!none=>\scratchdimen=-2.5\scratchdimen,
+ \v!overlay=>\scratchdimen=-2.5\scratchdimen,
+ \v!standard=>\scratchdimen=\scratchdimen,
+ \s!unknown=>\scratchdimen=\@@FLOWoffset,
+ \s!default=>\scratchdimen=-2.5\scratchdimen]%
+ \edef\@@FLOW@@offset{\the\scratchdimen}%
+ \forgetall
+ \offinterlineskip
+ \resetMPdrawing
+ \doglobal\newcounter\FLOWcomment
+ \startMPdrawing
+ if unknown context_char : input mp-char.mpii ; fi ;
+ grid_width := \FLOWgridwidth ;
+ grid_height := \FLOWgridheight ;
+ shape_width := \FLOWshapewidth ;
+ shape_height := \FLOWshapeheight ;
+ connection_line_width := \@@FLOLrulethickness ;
+ connection_smooth_size := \@@FLOLradius ;
+ connection_arrow_size := \@@FLOLradius ;
+ connection_dash_size := \@@FLOLradius ;
+ currentpicture := nullpicture ;
+ begin_chart(0,\FLOWwidth,\FLOWheight);
+ reverse_y := true ;
+ chart_offset := \@@FLOW@@offset ;
+ \stopMPdrawing
+ \doifelsenothing\@@FLOWbackgroundcolor
+ {\startMPdrawing
+ chart_background_color := white ;
+ \stopMPdrawing}
+ {\startMPdrawing
+ chart_background_color := \MPcolor{\@@FLOWbackgroundcolor} ;
+ \stopMPdrawing}%
+ \doif\@@FLOWoption\v!test
+ {\startMPdrawing
+ show_con_points := true ;
+ show_mid_points := true ;
+ show_all_points := true ;
+ \stopMPdrawing}%
+ \processaction % private
+ [\@@FLOWdot]
+ [ \v!yes=>\startMPdrawing
+ show_con_points := true ;
+ show_mid_points := true ;
+ show_all_points := true ;
+ \stopMPdrawing,
+ \s!unknown=>\startMPdrawing
+ show_\@@FLOWdot_points := true ;
+ \stopMPdrawing]%
+\doglobal\newcounter\FLOWcomment
+ \let\startFLOWcell\startFLOWcellB
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber
+\doglobal\newcounter\FLOWcomment
+ \let\startFLOWcell\startFLOWcellC
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber
+ \startMPdrawing
+ clip_chart(\@@FLOWx,\@@FLOWy,\@@FLOWnx,\@@FLOWny) ;
+ end_chart ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \setbox0\hbox
+ {\MPstaticgraphictrue
+ \MPshiftdrawingfalse
+ \getMPdrawing}%
+ \def\MPmessage##1%
+ {\writestatus{MP charts}{##1}}%
+ \def\MPposition##1##2##3%
+ {\setvalue{\@@MPx##1}{##2}\setvalue{\@@MPy##1}{##3}}%
+ \def\MPclippath##1##2##3##4%
+ {\def\clipMPllx{##1bp}\def\clipMPlly{##2bp}%
+ \def\clipMPurx{##3bp}\def\clipMPury{##4bp}}%
+ \def\MPareapath##1##2##3##4%
+ {\def\areaMPllx{##1bp}\def\areaMPlly{##2bp}%
+ \def\areaMPurx{##3bp}\def\areaMPury{##4bp}}%
+ \getMPdata
+ \doglobal\newcounter\FLOWcomment
+ \let\startFLOWcell\startFLOWcellD
+ \setbox2\vbox to \ht0
+ {\forgetall % \offinterlineskip
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber\vss}%
+ \setbox2\hbox
+ {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box2}%
+ \wd2\wd0\ht2\ht0\dp2\dp0
+ \let\startFLOWcell\startFLOWcellE
+ \setbox4\vbox to \ht0
+ {\forgetall % \offinterlineskip
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber\vss}%
+ \setbox4\hbox
+ {\hskip\@@FLOW@@offset\lower\@@FLOW@@offset\box4}%
+ \wd4\wd0\ht4\ht0\dp4\dp0
+ \doifelse\@@FLOWoption\v!test
+ {\setbox6\vbox
+ {\forgetall
+ \vskip\@@FLOW@@offset
+ \hskip\@@FLOW@@offset
+ \basegrid
+ [\c!x=\@@FLOWx,\c!nx=\@@FLOWnx,\c!dx=\withoutpt\FLOWgridwidth,
+ \c!y=\@@FLOWy,\c!ny=\@@FLOWny,\c!dy=\withoutpt\FLOWgridheight,
+ \c!xstep=1,\c!ystep=1,
+ \c!unit=pt,\c!location=\v!middle]}%
+ \wd6\wd0\ht6\ht0\dp6\dp0
+ \setbox8\vbox
+ {\forgetall
+ \offinterlineskip
+ \vskip\@@FLOW@@offset
+ \dostepwiserecurse\@@FLOWy\@@FLOWny\plusone
+ {\vbox to \FLOWgridheight
+ {\vfill
+ \hskip\@@FLOW@@offset
+ \hbox
+ {\dostepwiserecurse\@@FLOWx\@@FLOWnx\plusone
+ {\hbox to \FLOWgridwidth
+ {\hfill
+ \framed
+ [\c!framecolor=red,
+ \c!width=\FLOWshapewidth,
+ \c!height=\FLOWshapeheight]
+ {}%
+ \hfill}}}
+ \vfill}}}%
+ \wd8\wd0\ht8\ht0\dp8\dp0
+ \framed
+ [\c!offset=\v!overlay,\c!framecolor=green]
+ {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2\hskip-\wd6\box6\hskip-\wd8\box8}}}
+ {\framed
+ [\c!offset=\v!overlay,
+ \c!frame=\@@FLOWframe,
+ \c!rulethickness=\@@FLOWrulethickness,
+ \c!framecolor=\@@FLOWframecolor,
+ \c!background=\@@FLOWbackground,
+ \c!backgroundcolor=\@@FLOWbackgroundcolor]
+ {\hbox{\box4\hskip-\wd0\box0\hskip-\wd2\box2}}}%
+ %\message{[\FLOWcells]}\wait
+ \egroup}
+
+% Pass A
+
+\long\def\startFLOWcellA#1\stopFLOWcell%
+ {\resetFLOWcell
+ \ignorespaces#1\unskip
+ \expandafter\getFLOWlocationA\FLOWlocation\end
+ \ignorespaces}
+
+\def\getFLOWlocationA#1,#2\end
+ {\ifnum0#1>\FLOWwidth \xdef\FLOWwidth {#1}\fi
+ \ifnum0#2>\FLOWheight\xdef\FLOWheight{#2}\fi}
+
+% Pass B
+%
+% beware: the - after \@FLOC@ is needed since name can be
+% empty and we don't want to redefine \@FLOC@ itself by
+% mistake
+
+\long\def\startFLOWcellB#1\stopFLOWcell
+ {\resetFLOWcell\ignorespaces#1\unskip
+ \setxvalue{\@FLOC@-\FLOWname}{\FLOWlocation}% kost veel cs's
+ \ifx\FLOWshape\empty
+ \global\let\FLOWshape\@@FLOSdefault
+ \fi
+ \doifnot\FLOWshape{none} % {\v!none}
+ {\ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWshapes}
+ {\edef\FLOWshapetag{shape_\FLOWshape}% beter \expanded
+ \@EA\setFLOWname\@EA\FLOWshapetag\@EA{\FLOWshapetag}}
+ {\doifnumberelse\FLOWshape
+ {\let\FLOWshapetag\FLOWshape}
+ {\let\FLOWshapetag\empty}}%
+ \ifx\FLOWshapetag\empty \else
+ \ExpandBothAfter\doifinsetelse{\FLOWshape}{\FLOWlines}
+ {\chardef\FLOWstate0 }
+ {\ExpandBothAfter\doifcommonelse{\FLOWcell,\FLOWfocus}{\@@FLOWfocus}
+ {\chardef\FLOWstate1 }
+ {\chardef\FLOWstate2 }}%
+ \startMPdrawing
+ begin_sub_chart ;
+ \ifcase\FLOWstate
+ shape_line_color := \MPcolor{\@@FLOLcolor} ;
+ shape_fill_color := \MPcolor{\@@FLOLcolor} ;
+ shape_line_width := \@@FLOLrulethickness ;
+ \or
+ shape_line_color := \MPcolor{\@@FLOFframecolor} ;
+ shape_fill_color := \MPcolor{\@@FLOFbackgroundcolor} ;
+ shape_line_width := \@@FLOFrulethickness ;
+ \or
+ shape_line_color := \MPcolor{\@@FLOSframecolor} ;
+ shape_fill_color := \MPcolor{\@@FLOSbackgroundcolor} ;
+ shape_line_width := \@@FLOSrulethickness ;
+ \fi
+ %\ifx\FLOWoverlay\empty
+ % peepshape := false ;
+ %\else
+ % peepshape := true ;
+ %\fi
+ peepshape := \ifx\FLOWoverlay\empty false \else true \fi ;
+ new_shape(\FLOWlocation,\FLOWshapetag) ;
+ end_sub_chart ;
+ \stopMPdrawing
+ \fi}%
+ \ignorespaces}
+
+% Pass C
+
+\long\def\startFLOWcellC#1\stopFLOWcell%
+ {\resetFLOWcell
+\pushmacro\lastFLOWx
+\pushmacro\lastFLOWy
+ \ignorespaces#1\unskip % makes sure that vars are set
+\popmacro\lastFLOWy
+\popmacro\lastFLOWx
+ \let\connection\doFLOWconnectionC
+ \ignorespaces#1\unskip}
+
+\def\FLOWorigin{0,0}
+
+\def\doFLOWdisplace[#1,#2,#3]% experiment
+ {dsp_x := #1 ; dsp_y := #2 ;}
+
+\def\doFLOWconnectionC
+ {\dodoubleempty\dodoFLOWconnectionC}
+
+\def\dodoFLOWconnectionC[#1][#2]#3%
+ {\doglobal\increment\FLOWcomment
+ \setFLOWname\otherFLOWname{name_#3}%
+ \doifdefinedelse{\@FLOC@-\FLOWname}
+ {\edef\FLOWfrom{\getvalue{\@FLOC@-\FLOWname}}}
+ {\let \FLOWfrom \FLOWorigin}%
+ \ifx\FLOWfrom\FLOWorigin \else
+ \doifdefinedelse{\@FLOC@-\otherFLOWname}
+ {\edef\FLOWto {\getvalue{\@FLOC@-\otherFLOWname}}}
+ {\let \FLOWto \FLOWorigin}%
+ \ifx\FLOWto\FLOWorigin \else
+ \FLOWsetconnect{#1}%
+ \ifx\cFLOWfrom\empty \else
+ \doifelse\@@FLOLcorner\v!round
+ {\startMPdrawing smooth := true ; \stopMPdrawing}
+ {\startMPdrawing smooth := false ; \stopMPdrawing}%
+ \doifelse\@@FLOLdash\v!yes
+ {\startMPdrawing dashline := true ; \stopMPdrawing}
+ {\startMPdrawing dashline := false ; \stopMPdrawing}%
+ \doifelse\@@FLOLarrow\v!yes
+ {\startMPdrawing arrowtip := true ; \stopMPdrawing}
+ {\startMPdrawing arrowtip := false ; \stopMPdrawing}%
+ \doifelse\@@FLOLoffset\v!none
+ {\startMPdrawing touchshape := true ; \stopMPdrawing}
+ {\startMPdrawing touchshape := false ; \stopMPdrawing}%
+%\doifsomething{#2}
+% {\startMPdrawing
+% \doFLOWdisplace[0#2,0,0]%
+% \stopMPdrawing}%
+ \startMPdrawing
+\doFLOWdisplace[0#2,0,0]%
+ connection_line_color := \MPcolor{\@@FLOLcolor} ;
+ connection_line_width := \@@FLOLrulethickness ;
+ connect_\cFLOWfrom_\cFLOWto (\FLOWfrom,\zFLOWfrom) (\FLOWto,\zFLOWto) ;
+\doFLOWdisplace[0,0,0]%
+ \stopMPdrawing
+ \fi
+ \fi
+ \fi
+ \ignorespaces}
+
+% Pass D
+
+\long\def\startFLOWcellD#1\stopFLOWcell
+ {\resetFLOWcell
+\pushmacro\lastFLOWx
+\pushmacro\lastFLOWy
+ \ignorespaces#1\unskip % presets vars
+\popmacro\lastFLOWy
+\popmacro\lastFLOWx
+ \let\doprocessFLOWcell\doprocessFLOWcellD
+ \expandafter\doprocessFLOWcellD\FLOWlocation\end
+ \let\connection\doFLOWconnectionD
+ \let\comment\doFLOWcommentD
+ \ignorespaces#1\unskip\ignorespaces}
+
+\def\doFLOWconnectionD
+ {\dodoubleempty\dodoFLOWconnectionD}
+
+\def\dodoFLOWconnectionD[#1][#2]#3%
+ {\doglobal\increment\FLOWcomment
+ \ignorespaces}
+
+\def\doFLOWcommentD[#1]#2%
+ {\bgroup
+ \let\FLOW \middlebox
+ \let\FLOWb \bottombox
+ \let\FLOWbl\bottomleftbox
+ \let\FLOWbr\bottomrightbox
+ \let\FLOWt \topbox
+ \let\FLOWtl\topleftbox
+ \let\FLOWtr\toprightbox
+ \let\FLOWl \leftbox
+ \let\FLOWlt\lefttopbox
+ \let\FLOWlb\leftbottombox
+ \let\FLOWr \rightbox
+ \let\FLOWrt\righttopbox
+ \let\FLOWrb\rightbottombox
+ \let\FLOWc \middlebox
+%\ifdefined{FLOW#1}%
+ \ifcase0\getvalue{\@@MPx\FLOWcomment}\getvalue{\@@MPy\FLOWcomment}\relax
+ \else
+ \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp<\areaMPllx\relax\else
+ \ifdim\getvalue{\@@MPx\FLOWcomment}\s!bp>\areaMPurx\relax\else
+ \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp<\areaMPlly\relax\else
+ \ifdim\getvalue{\@@MPy\FLOWcomment}\s!bp>\areaMPury\relax\else
+ \dimen0=\getvalue{\@@MPx\FLOWcomment}\s!bp
+ \advance\dimen0 -\@@FLOW@@offset
+ \advance\dimen0 -\clipMPllx
+ \dimen2=\clipMPury
+ \advance\dimen2 -\@@FLOW@@offset
+ \advance\dimen2 -\getvalue{\@@MPy\FLOWcomment}\s!bp
+ \setbox\scratchbox\hbox{\strut#2}%
+ \boxoffset.5\bodyfontsize
+ \setbox\scratchbox\hbox{\hskip\dimen0\lower\dimen2\getvalue{FLOW#1}{\box\scratchbox}}%
+ \smashbox\scratchbox
+ \box\scratchbox
+ \boxoffset\zeropoint
+ \nointerlineskip % really needed
+ \fi
+ \fi
+ \fi
+ \fi
+ \fi
+%\fi
+ \egroup
+ \ignorespaces}
+
+% pass D
+
+\def\dophaseoneFLOWcellX#1#2%
+ {\!!counta#1\relax
+ \!!countb#2\relax
+ \!!countc\@@FLOWx
+ \!!countd\@@FLOWy
+ \advance\!!countc \@@FLOWnx
+ \advance\!!countd \@@FLOWny
+ \advance\!!countc \minusone
+ \advance\!!countd \minusone
+ \ifnum\!!counta<\@@FLOWx\relax \donefalse
+ \else\ifnum\!!counta>\!!countc \donefalse
+ \else\ifnum\!!countb<\@@FLOWy\relax \donefalse
+ \else\ifnum\!!countb>\!!countd \donefalse
+ \else \donetrue
+ \fi\fi\fi\fi}
+
+\def\dophasetwoFLOWcellX
+ {\advance\!!counta -\@@FLOWx
+ \advance\!!counta \plusone
+ \advance\!!countb -\@@FLOWy
+ \advance\!!countb \plusone
+ \dimen0=\FLOWgridwidth
+ \dimen0=\!!counta\dimen0
+ \advance\dimen0 -\FLOWgridwidth
+ \dimen4=\FLOWgridwidth
+ \advance\dimen4 -\FLOWshapewidth
+ \advance\dimen0 .5\dimen4
+ \dimen2=\FLOWgridheight
+ \dimen2=\!!countb\dimen2
+ \dimen4=\FLOWgridheight
+ \advance\dimen4 -\FLOWshapeheight
+ \advance\dimen2 -.5\dimen4
+ \edef\FLOWdx{\the\dimen0}%
+ \edef\FLOWdy{\the\dimen2}}
+
+\def\positionFLOWzero% assumes \FLOWdx and \FLOWdy are set
+ {\setbox0\hbox{\hskip\FLOWdx\lower\FLOWdy\box0}%
+ \smashbox0\box0
+ \nointerlineskip} % new, needed since we somehow reset that
+
+\def\doFLOWtlabel#1#2#3%
+ {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi
+ \setbox0\hbox{\hskip\dimen2\raise\scratchdimen
+ \hbox{\raise\dimen4\hbox{#1{\strut#3}}}}%
+ \positionFLOWzero}%
+
+\def\doFLOWblabel#1#2#3%
+ {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdy\fi
+ \setbox0\hbox{\hskip\dimen2\raise-\scratchdimen
+ \hbox{#1{\strut#3}}}%
+ \positionFLOWzero}%
+
+\def\doFLOWllabel#1#2#3%
+ {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi
+ \setbox0\hbox{\hskip-\scratchdimen\raise\dimen6
+ \hbox{#1{\strut#3}}}%
+ \positionFLOWzero}%
+
+\def\doFLOWrlabel#1#2#3%
+ {\scratchdimen\ifcase#2 \zeropoint\else\@@FLOWdx\fi
+ \setbox0\hbox{\hskip\dimen0\hskip\scratchdimen
+ \hbox{\raise\dimen6\hbox{#1{\strut#3}}}}%
+ \positionFLOWzero}
+
+\def\doprocessFLOWcellD#1,#2\end
+ {\dophaseoneFLOWcellX{#1}{#2}%
+ \ifdone
+ \dophasetwoFLOWcellX
+ \doglobal\addtocommalist\FLOWcell\FLOWcells
+ \def\FLOWx{#1}%
+ \def\FLOWy{#2}%
+ \directsetup{flowcell}%
+ \setbox0\hbox
+ {\ifx\FLOWalign\empty\else
+ \setupframed
+ [\c!align=\v!normal,\c!bottom=\vfill,\c!top=\vfill]%
+ \@EA\processallactionsinset\@EA
+ [\FLOWalign]
+ [t=>{\setupframed[\c!bottom=\vfill,\c!top=]},
+ b=>{\setupframed[\c!bottom=,\c!top=\vfill]},
+ l=>{\setupframed[\c!align=\v!right]},
+ r=>{\setupframed[\c!align=\v!left]},
+ m=>{\setupframed[\c!align=\v!middle]},
+ c=>{\setupframed[\c!align=\v!middle]}]%
+ \fi
+ \doifelse\FLOWshape{none} % {\v!none}
+ {\setupframed[\c!offset=\v!overlay]}
+ {\setupframed[\c!offset=\@@FLOSoffset]}%
+ \framed
+ [\c!frame=\v!off,\c!background=flowcell,
+ \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight]
+ {\FLOWtext}}%
+ \showFLOWhelp0
+ \ifx\FLOWdestination\empty\else
+ \setbox0\hbox
+ {\setupinteraction[\c!color=,\c!contrastcolor=]%
+ \gotobox{\box0}[\FLOWdestination]}%
+ \fi
+ \positionFLOWzero
+ \dimen0=\FLOWshapewidth \dimen2=.5\dimen0
+ \dimen4=\FLOWshapeheight\dimen6=.5\dimen4
+ \boxoffset.5\bodyfontsize
+ \doFLOWtlabel \righttopbox0\tFLOWlabel
+ \doFLOWblabel\rightbottombox0\bFLOWlabel
+ \doFLOWllabel \lefttopbox0\lFLOWlabel
+ \doFLOWrlabel \righttopbox0\rFLOWlabel
+ \doFLOWtlabel \topbox0\tcFLOWlabel % for me only
+ \doFLOWblabel \bottombox0\bcFLOWlabel % for me only
+ \doFLOWllabel \leftbox0\lcFLOWlabel % for me only
+ \doFLOWrlabel \rightbox0\rcFLOWlabel % for me only
+ \ifnum#1=\@@FLOWx\relax \doFLOWllabel \leftbox1\lFLOWexit \fi
+ \ifnum#1=\!!countc \doFLOWrlabel \rightbox1\rFLOWexit \fi
+ \ifnum#2=\@@FLOWy\relax \doFLOWtlabel \topbox1\tFLOWexit \fi
+ \ifnum#2=\!!countd \doFLOWblabel \bottombox1\bFLOWexit \fi
+ \boxoffset\zeropoint
+ \fi}
+
+% For Willy Egger:
+%
+% \startsetups flowcell
+% \definelayer
+% [flowcell]
+% [width=\FLOWshapewidth,
+% height=\FLOWshapeheight]
+% \setlayerframed
+% [flowcell]
+% [preset=rightbottom,offset=1ex]
+% [frame=off]
+% {\tx(\FLOWx,\FLOWy)}
+% \stopsetups
+
+% Pass E
+
+\long\def\startFLOWcellE#1\stopFLOWcell
+ {\resetFLOWcell
+ \ignorespaces#1\unskip
+ \let\doprocessFLOWcell\doprocessFLOWcellE
+ \expandafter\doprocessFLOWcell\FLOWlocation\end}
+
+\def\doprocessFLOWcellE#1,#2\end % redundant
+ {\ifx\FLOWoverlay\empty \else
+ \dophaseoneFLOWcellX{#1}{#2}%
+ \ifdone
+ \dophasetwoFLOWcellX
+ \edef\FLOWdx{\the\dimen0}%
+ \edef\FLOWdy{\the\dimen2}%
+ \setbox0\hbox
+ {\framed
+ [%\c!frame=\v!off,
+ \c!background={\@@FLOWbackground,\FLOWoverlay},
+ \c!backgroundcolor=\@@FLOSbackgroundcolor,
+ \c!width=\FLOWshapewidth,\c!height=\FLOWshapeheight]
+ {}}%
+ \positionFLOWzero
+ \fi
+ \fi}
+
+% Pass F
+
+\def\checkFLOWautofocus
+ {\def\@@FLOWminx{100}\let\@@FLOWminy\@@FLOWminx
+ \def\@@FLOWmaxx {0}\let\@@FLOWmaxy\@@FLOWmaxx
+ \def\@@FLOWabsx {0}\let\@@FLOWabsy\@@FLOWabsx
+ \let\startFLOWcell\startFLOWcellF
+ \resetFLOWlocation
+ \processFLOWbuffer\currentFLOWnumber
+ %\message{AUTOSHAPE 1: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}%
+ \ifnum\@@FLOWabsx<\@@FLOWmaxx\let\@@FLOWmaxx\@@FLOWabsx\fi
+ \ifnum\@@FLOWabsy<\@@FLOWmaxy\let\@@FLOWmaxy\@@FLOWabsy\fi
+ %\message{AUTOSHAPE 2: (\@@FLOWminx,\@@FLOWminy)->(\@@FLOWmaxx,\@@FLOWmaxy)}%
+ \donetrue
+ \ifnum\@@FLOWminx=100 \donefalse\fi
+ \ifnum\@@FLOWminy=100 \donefalse\fi
+ \ifnum\@@FLOWmaxx=0 \donefalse\fi
+ \ifnum\@@FLOWmaxy=0 \donefalse\fi
+ \doFLOWcheckF\@@FLOWx\@@FLOWminx\@@FLOWmaxx\@@FLOWnx
+ \doFLOWcheckF\@@FLOWy\@@FLOWminy\@@FLOWmaxy\@@FLOWny}
+
+\def\startFLOWcellF#1\stopFLOWcell%
+ {\resetFLOWcell
+ \ignorespaces#1\unskip
+ \expandafter\doFLOWlocationF\FLOWlocation\end}%
+
+\def\doFLOWlocationF#1,#2\end%
+ {\ifnum#1>\@@FLOWabsx\def\@@FLOWabsx{#1}\fi
+ \ifnum#2>\@@FLOWabsy\def\@@FLOWabsy{#2}\fi
+ \ExpandBothAfter\doifinset{\FLOWcell}{\@@FLOWautofocus}
+ {\dodoFLOWlocationF{#1}<-\@@FLOWminx
+ \dodoFLOWlocationF{#1}>+\@@FLOWmaxx
+ \dodoFLOWlocationF{#2}<-\@@FLOWminy
+ \dodoFLOWlocationF{#2}>+\@@FLOWmaxy}}
+
+\def\dodoFLOWlocationF#1#2#3#4%
+ {\ifnum#1#2#4\relax
+ \!!counta=#1\advance\!!counta #31\relax
+ \edef#4{\ifnum\!!counta<1 1\else\the\!!counta\fi}%
+ \fi}
+
+\def\doFLOWcheckF#1#2#3#4%
+ {\ifdone
+ \let#1=#2%
+ \!!counta=#3%
+ \advance\!!counta \plusone\advance\!!counta -#2\relax
+ \ifnum\!!counta<1 \!!counta=1 \fi
+ \edef#4{\the\!!counta}%
+ \else
+ \let#1\!!plusone
+ \let#4\!!zerocount % no {1}
+ \fi}
+
+% \useFLOWchart[name][parent][setting,setting][additional settings]
+% \useFLOWchart[name][parent][additional settings]
+
+\let\currentFLOWchart\empty
+
+\def\useFLOWchart
+ {\doquadrupleempty\douseFLOWchart}
+
+\def\douseFLOWchart[#1][#2][#3][#4]% name parent sets mainsettings
+ {\iffourthargument
+ \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][#4,##1]}%
+ \else
+ \checkparameters[#3]%
+ \ifparameters
+ \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][][#3,##1]}%
+ \else
+ \setvalue{\@FLOW@--#1}[##1]{\setgetFLOWchart[#2][#3][##1]}%
+ \fi
+ \fi}
+
+\def\setgetFLOWchart[#1][#2][#3]%
+ {\def\docommand##1{}% cell line focus ?
+ \processcommalist[#2]\docommand
+ \getFLOWchart[#1][#3]}
+
+\def\doFLOWchart[#1][#2]%
+ {\hbox\bgroup\vbox\bgroup % vmode suppresses spaces
+\def\currentFLOWchart{#1}%
+ \doifundefinedelse{\@FLOW@--#1}
+ {\getFLOWchart[#1][#2]}
+ {\getvalue{\@FLOW@--#1}[#2]}%
+ \egroup\egroup}
+
+\def\FLOWchart%
+ {\dodoubleempty\doFLOWchart}
+
+%D A hook into the help system.
+
+\def\showFLOWhelp#1%
+ {\doifhelpinfo\FLOWhelp
+ {\setbox#1=\hbox
+ {\setbox\scratchbox=\hbox{\lower\@@FLOWdy\hbox
+ {\helpbutton
+ [\c!width=\wd0,\c!color=,\c!height=\@@FLOWdy,\c!frame=\v!no]%
+ [\FLOWhelp]}}%
+ \smashbox\scratchbox
+ \setbox#1=\vbox
+ {\forgetall\offinterlineskip\box#1\box\scratchbox}%
+ \box#1}}}
+
+%D The next section is dedicated to splitting up charts.
+
+\def\getFLOWsize[#1]%
+ {\bgroup\let\dodogetFLOWchart\dogetFLOWsize\FLOWchart[#1]\egroup}
+
+\def\dogetFLOWsize[#1][#2]%
+ {\setbox\scratchbox=\vbox
+ {\globallet\FLOWmaxwidth \!!zerocount
+ \globallet\FLOWmaxheight\!!zerocount
+ \def\getFLOWlocation##1,##2\end
+ {\ifnum0##1>\FLOWmaxwidth \xdef\FLOWmaxwidth {##1}\fi
+ \ifnum0##2>\FLOWmaxheight\xdef\FLOWmaxheight{##2}\fi}%
+ \resetFLOWcell
+ \long\def\startFLOWcell##1\stopFLOWcell
+ {{##1\expandafter\getFLOWlocation\FLOWlocation\end}}%
+ \def\dohandleflowchart[##1][##2]%
+ {\resetFLOWlocation
+ \processFLOWbuffer{##1}}%
+ \getvalue{\@FLOW@-#1}}}
+
+\def\setupFLOWsplit%
+ {\dodoubleargument\getparameters[\@@FLOT]}
+
+\setupFLOWsplit%
+ [\c!nx=3,\c!ny=3,
+ \c!dx=1,\c!dy=1,
+ \c!command=,
+ \c!marking=\v!on,
+ \c!before=,\c!after=]
+
+\def\FLOWsplitx {1}
+\def\FLOWsplity {1}
+\def\FLOWsplitnx{1}
+\def\FLOWsplitny{1}
+
+\def\FLOWcharts
+ {\dodoubleempty\doFLOWcharts}
+
+%D While splitting, the following variables are available:
+%D
+%D \starttyping
+%D \FLOWsplitnx \FLOWsplitny \FLOWsplitx \FLOWsplity
+%D \stoptyping
+
+\def\doFLOWcharts[#1][#2]%
+ {\bgroup
+ \getFLOWsize[#1]%
+ \dodoFLOWcharts\relax
+ \global\let\FLOWsplitnx\FLOWsplitx
+ \global\let\FLOWsplitny\FLOWsplity
+ \dodoFLOWcharts{\dododoFLOWcharts[#1][#2]}%
+ \egroup}
+
+\def\dodoFLOWcharts#1%
+ {\def\@@FLOTx{1}%
+ \global\let\FLOWsplitx\@@FLOTx
+ \doloop
+ {\def\@@FLOTy{1}%
+ \global\let\FLOWsplity\@@FLOTy
+ \doloop
+ {\bgroup
+ \scratchcounter\FLOWmaxwidth
+ \advance\scratchcounter -\@@FLOTx
+ \advance\scratchcounter \plusone
+ \ifnum\scratchcounter<\@@FLOTnx\edef\@@FLOTnx{\the\scratchcounter}\fi
+ \scratchcounter\FLOWmaxheight
+ \advance\scratchcounter -\@@FLOTy
+ \advance\scratchcounter \plusone
+ \ifnum\scratchcounter<\@@FLOTny\edef\@@FLOTny{\the\scratchcounter}\fi
+ #1% does something with the float, or not
+ \egroup
+ \increment(\@@FLOTy,\@@FLOTny)%
+ \ifnum\@@FLOTy>\FLOWmaxheight
+ \exitloop
+ \else
+ \doglobal\increment\FLOWsplity
+ \decrement(\@@FLOTy,\@@FLOTdy)%
+ \fi}%
+ \increment(\@@FLOTx,\@@FLOTnx)%
+ \ifnum\@@FLOTx>\FLOWmaxwidth
+ \exitloop
+ \else
+ \doglobal\increment\FLOWsplitx
+ \decrement(\@@FLOTx,\@@FLOTdx)%
+ \fi}}
+
+\def\dododoFLOWcharts[#1][#2]%
+ {\bgroup
+ \@@FLOTbefore
+ \doifnot\@@FLOTmarking\v!on{\let\cuthbox\hbox}%
+ \cuthbox
+ {\@@FLOTcommand
+ {\FLOWchart[#1][#2,
+ \c!x=\@@FLOTx,\c!nx=\@@FLOTnx,
+ \c!y=\@@FLOTy,\c!ny=\@@FLOTny]}}%
+ \@@FLOTafter
+ \egroup}
+
+%D An example of splitting is given below:
+%D
+%D \starttyping
+%D \setupFLOWsplit
+%D [nx=5,ny=10,
+%D dx=0,dy=0,
+%D before=,
+%D after=\page]
+%D
+%D \FLOWcharts[mybigflow]
+%D \stoptyping
+%D
+%D Or, one can say:
+%D
+%D \starttyping
+%D \splitfloat
+%D {\placefigure{What a big flowchart this is!}}
+%D {\FLOWcharts[mybigflow]}
+%D \stoptyping
+
+%D \macros
+%D {typeFLOWchart}
+%D
+%D For documentation purposes the following macro is
+%D provided. Watch the use of the first and last line hooks,
+%D which is needed because the start and stop commands are
+%D not part of the buffer.
+
+\def\typeFLOWchart[#1]%
+ {\bgroup
+ \def\dohandleflowchart[##1][##2]{\typeFLOWbuffer{##1}}%
+ \defconvertedargument\firstverbatimfileline{\startFLOWchart[#1]}%
+ \defconvertedargument\lastverbatimfileline {\stopFLOWchart}%
+ \getvalue{\@FLOW@-#1}
+ \egroup}
+
+%D New:
+%D
+%D \starttyping
+%D \setupFLOWcharts[command=\Whow]
+%D
+%D \startFLOWset[convert-en] % [tag][convert-en]
+%D \subFLOWchart[a][x=1,y=1,nx=3,ny=3]
+%D \subFLOWchart[b][x=1,y=2,nx=3,ny=3]
+%D \subFLOWchart[c][x=2,y=1,nx=3,ny=3]
+%D \stopFLOWset
+%D
+%D \def\Whow#1%
+%D {\ifnum\currentFLOWset=1 \framed{Some Chart}\fi}
+%D
+%D \FLOWset[convert-en] % [tag]
+%D
+%D \def\Whow#1%
+%D {\setuphead[state=high]
+%D \startstandardmakeup
+%D \centerbox{#1}
+%D \stopstandardmakeup}
+%D
+%D \FLOWset[convert-en] % [tag]
+%D \stoptyping
+
+\def\startFLOWset
+ {\dodoubleempty\dostartFLOWset}
+
+\def\dostartFLOWset[#1][#2]#3\stopFLOWset % tag name data
+ {\ifsecondargument
+ \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#2}{#3}}%
+ \else
+ \long\setvalue{\@FLOX@#1}{\dohandleFLOWset{#1}{#1}{#3}}%
+ \fi}
+
+\long\def\dohandleFLOWset#1#2#3% tag name data
+ {\bgroup
+ \def\subFLOWchart
+ {\dodoubleempty\dosubFLOWchart}%
+ \def\dosubFLOWchart[##1][##2]% subtag settings
+ {\ifsecondargument
+ \dodohandleFLOWset{#1}{##1}{#2}{##2}%
+ \else
+ \subFLOWchart[][##1]%
+ \fi}%
+ #3%
+ \egroup}
+
+\def\dodohandleFLOWset#1#2#3#4% tag subtag name settings
+ {\increment\currentFLOWset
+ \bgroup
+ \@@FLOXcommand
+ {\ifnum\currentFLOWset=1 \pagereference[#1]\fi
+ \doifsomething{#2}
+ {\setupreferencing[\c!prefix=]%
+ \pagereference[#1:#2]% -:#1:#2
+ \setupreferencing[\c!prefix=#1:#2]}%
+ \FLOWchart[#3][#4]}%
+ \egroup}
+
+\def\FLOWset[#1]%
+ {\newcounter\currentFLOWset
+ \doifdefinedelse{\@FLOX@#1}
+ {\getvalue{\@FLOX@#1}}
+ {\dodohandleFLOWset{#1}{}{#1}{}}}
+
+\newcounter\currentFLOWset
+
+\setupFLOWsets
+ [\c!command=]
+
+%D This will be an option:
+
+% \def\startFLOWchart%
+% {\dodoubleempty\dostartFLOWchart}
+%
+% \long\def\dostartFLOWchart[#1][#2]#3\stopFLOWchart
+% {\preparenextFLOWchart{#1}{#2}%
+% \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}}
+%
+% \long\def\dodefineFLOWchart[#1][#2]#3%
+% {\preparenextFLOWchart{#1}{#2}%
+% \long\setgvalue{\FLOWbufferprefix\nofFLOWcharts}{#3}}
+%
+% \def\processFLOWbuffer#1{\getvalue{\FLOWbufferprefix#1}}
+% \def\typeFLOWbuffer #1{[Sorry, no verbatim chart #1 available.]}
+
+%D The \XML\ interface:
+
+\startXMLdefinitions flowchart
+
+\defineXMLargument [flowchartdefinition]
+ {\defineFLOWchart[\XMLpar{flowchartdefinition}{identifier}{unknown}]}
+
+\defineXMLpickup [flowcell]
+ {\startFLOWcell
+ \defineXMLargument[name]{\unspaceafter\name}%
+ \defineXMLargument[shape]{\unspaceafter\shape}%
+ \defineXMLnestedargument[text]{\text}}
+ {\stopFLOWcell}
+
+\defineXMLenvironment [location] % global unspace/store
+ {\bgroup\defineXMLpush[x]\defineXMLpush[y]}
+ {\XMLunspace{x}\XMLunspace{y}%
+ \expanded{\egroup\noexpand\location{\XMLpop{x},\XMLpop{y}}}}
+
+\defineXMLenvironment [connection]
+ {\bgroup\defineXMLpush[type]\defineXMLpush[name]}%
+ {\XMLunspace{type}\XMLunspace{name}%
+ \expanded{\egroup\noexpand\connection[\XMLpop{type}]{\XMLpop{name}}}}
+
+\defineXMLsingular [flowchart]
+ {\expanded{\FLOWchart[\XMLpar{flowchart}{identifier}{unknown}]}}
+
+\defineXMLdirective [flowchart] [shapes] \setupFLOWshapes
+\defineXMLdirective [flowchart] [lines] \setupFLOWlines
+
+\stopXMLdefinitions
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-chemic.mkii b/tex/context/modules/mkii/m-chemic.mkii
new file mode 100644
index 000000000..0b3c98221
--- /dev/null
+++ b/tex/context/modules/mkii/m-chemic.mkii
@@ -0,0 +1,21 @@
+%D \module
+%D [ file=ppchtex (m-chemic),
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten},
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifx\psaxes\undefined \ifx\beginpicture\undefined
+ \usemodule[pictex]
+\fi \fi
+
+\input ppchtex.mkii \relax
+
+\endinput
diff --git a/tex/context/modules/mkii/m-cweb.mkii b/tex/context/modules/mkii/m-cweb.mkii
new file mode 100644
index 000000000..bf80e229c
--- /dev/null
+++ b/tex/context/modules/mkii/m-cweb.mkii
@@ -0,0 +1,1371 @@
+%D \module
+%D [ file=m-cweb,
+%D version=1997.01.15,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\CWEB\ Pretty Printing Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D First some auxiliary stuff, to be moved to system module.
+
+\def\dodofindfirstcharacter#1%
+ {\ifx#1\relax
+ \let\next=\egroup
+ \else
+ \handlecase
+ {\expandafter\ifnum\expandafter\catcode\expandafter`#1=11
+ \def\next##1\relax{\egroup\def\firstcharacter{#1}}%
+ \fi}%
+ \fi
+ \next}
+
+\def\dofindfirstcharacter#1#2%
+ {\def\firstcharacter{}%
+ \bgroup
+ \defconvertedargument\ascii{#2}%
+ \let\next\dodofindfirstcharacter
+ \let\handlecase#1%
+ \expandafter\next\ascii\relax}
+
+\def\normalcase#1%
+ {#1}
+
+\def\findfirstcharacter%
+ {\dofindfirstcharacter\lowercase}
+
+\def\FindFirstCharacter%
+ {\dofindfirstcharacter\normalcase}
+
+\def\FINDFIRSTCHARACTER%
+ {\dofindfirstcharacter\uppercase}
+
+% nog doen:
+%
+% \deactivateCWEB in output routine
+% status info
+% gelinkte entries
+% parskip en parindent
+
+%D \gdef\CWEBquote#1.{{\em Quote :}\ #1.} % checks the .
+
+%D This module (re)implements the \CWEB\ macros as defined in
+%D the file \type{cwebmac.tex}.
+%D
+%D \CWEB\ uses short, often one character long, names for
+%D macros. This is no real problem because no one is supposed
+%D to read and understand the files generated by \CWEB. The
+%D standard macros are meant for \PLAIN\ \TEX\ users. In
+%D \CONTEXT\ and other macro packages however, there is a
+%D potential conflict with format specific or user defined
+%D commands. Furthermore, the \CWEB\ macros implement their own
+%D output routines. When integrating \CWEB\ documents in
+%D another environment, the \CWEB\ specific macros have to be
+%D made local. The first part of this module is dedicated to
+%D this feature.
+%D
+%D Instead of using \type{\def} and \type{\let} for defining
+%D macros, we use:
+%D
+%D \starttyping
+%D \defCEBmacro arguments {meaning}
+%D \letCEBmacro arguments {meaning}
+%D \stoptyping
+%D
+%D \CWEB files contain implicit calls to macros that generate
+%D the table of contents, the lists of sections and the index.
+%D Because we want to be much more flexible, we implemented our
+%D own alternatives, and therefore have to bypass the original
+%D ones. The next macro is used for defining these obsolete
+%D \CWEB\ macros. The dummies take care of arguments.
+%D
+%D \starttyping
+%D \defCEBdummy arguments {meaning}
+%D \stoptyping
+%D
+%D The list of \CWEB\ specific macro names is saved in a
+%D \TOKENLIST. This serves two purposes. First it enables us to
+%D activate the \CWEB\ macros, which are saved under a
+%D different name, second it can be used to temporary restore
+%D the meanings, for instance when the output routine builds
+%D the page.
+
+\newtoks\CWEBmacros
+
+%D Activating and deactivating is done by means of:
+%D
+%D \starttyping
+%D \activateCWEB
+%D \deactivateCWEB
+%D \stoptyping
+%D
+%D Which are implemented as:
+
+\def\activateCWEB%
+ {\let\doCWEB=\activateCWEBmacro
+ \the\CWEBmacros}
+
+\def\deactivateCWEB%
+ {\let\doCWEB=\deactivateCWEBmacro
+ \the\CWEBmacros}
+
+%D The three definition macros append the name of the macro to
+%D the list. The first two macros save the meaning, the last one
+%D assigns \type{{}} to the macro and gobbles original meaning.
+
+\long\def\defCWEBmacro#1%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \setvalue{newCWEB\string#1}}
+
+\long\def\letCWEBmacro#1%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \letvalue{newCWEB\string#1}}
+
+\long\def\defCWEBdummy#1#2#%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \setvalue{newCWEB\string#1}#2{}%
+ \gobbleoneargument}
+
+%D The macro \type{\defCWEBdummy} of course takes care of the
+%D argument. This leaves the two (de|)|activating macros:
+
+\def\CWEBmacro#1%
+ {\getvalue{newCWEB\string#1}}
+
+\def\activateCWEBmacro#1%
+ {\letvalue{oldCWEB\string#1}=#1%
+ \def#1{\CWEBmacro#1}}
+
+\def\deactivateCWEBmacro#1%
+ {\expandafter\let\expandafter#1\expandafter=\csname oldCWEB\string#1\endcsname}
+
+%D I did consider loading the \CWEB\ macros using temporary
+%D substitutes of \type{\def}, \type{\font}, \type{\newbox} etc.
+%D The main problem is that the file contains more than
+%D definitions and taking all kind of assignments into account
+%D too would not make things easier. So I decided to stick to
+%D the method as just described.
+
+%D Now we're ready for the real job. What follows is a partial
+%D adaption of the file \type{cwebmac.tex}, version 3.1, dated
+%D September 1994 and written by Levy and Knuth. When possible
+%D we kept the original meaning, but we've granted ourselves
+%D the freedom to reformat the macro's for readibility.
+%D
+%D We'll only present the macros we actually use. The source
+%D however contains the original implementation.
+
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 3.1 --- September 1994.
+%
+% \ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros
+%
+% \xdef\fmtversion{\fmtversion+CWEB3.1}
+
+%D \macros{.}{}
+%D
+%D \CWEBquote preserve a way to get the dot accent (all
+%D other accents will still work as usual).
+
+\letCWEBmacro\: = \.
+
+% \parskip = 0pt % no stretch between paragraphs
+% \parindent = 1em % for paragraphs and for the first line of C text
+
+% \font\ninerm = cmr9
+% \let\mc = \ninerm % medium caps
+% \font\eightrm = cmr8
+% \let\sc = \eightrm % small caps (NOT a caps-and-small-caps font)
+% \let\mainfont = \tenrm
+% \let\cmntfont = \tenrm
+% \font\tenss = cmss10
+% \let\cmntfont = \tenss % alternative comment font
+% \font\titlefont = cmr7 scaled \magstep4 % title on the contents page
+% \font\ttitlefont = cmtt10 scaled \magstep2 % typewriter type in title
+% \font\tentex = cmtex10 % TeX extended character set (used in strings)
+% \fontextraspace\tentex = 0pt % no double space after sentences
+
+%D \macros{mc,sc,cmntfont,eightrm}{}
+%D
+%D The naming of the fonts in in line with those in \PLAIN\
+%D \TEX. Although \CONTEXT\ implements its own scheme, there is
+%D still support for the \PLAIN\ ones. We keep the original
+%D names, but change their meaning. That way the macros obey
+%D switching to other sizes or styles.
+
+\defCWEBmacro\mc {\tx}
+\defCWEBmacro\sc {\txx}
+\defCWEBmacro\cmntfont {\ss}
+\defCWEBmacro\eightrm {\tx}
+
+%D \macros{tentex,sevenrm,sevensy,teni}{}
+%D
+%D The next one uses a temporary solution. The \type{cmtex10}
+%D font is not part of the default mechanism. We make use of
+%D the \CONTEXT\ variables \type{\textface}, \type{\scriptface}
+%D and \type{\scriptscriptface}, which hold the current
+%D sizes.
+
+\defCWEBmacro\tentex%
+ {\font\next=cmtex10 at \textface
+ \fontextraspace\next\zeropoint
+ \next}
+
+\defCWEBmacro\sevenrm {\getvalue{\scriptface rmtf}}
+\defCWEBmacro\sevensy {\getvalue{\scriptface mmsy}}
+\defCWEBmacro\teni {\getvalue{\textface mmmi}}
+
+%D \macros{CWEBpt}{}
+%D
+%D The original macros are based on a 10~point bodyfont size. We
+%D therefore have to specify dimension in points a bit
+%D different. Specifications like .6pt are changed to
+%D \type{.06} times \type{\bodyfontsize}.
+
+\defCWEBmacro\CWEBpt {\bodyfontsize} % still dutch
+
+%D \macros{CEE,UNIX,TEX,CPLUSPLUS}{}
+%D
+%D Next come some logo's. It does not make much sense to use
+%D the \CONTEXT\ logo mechanism here, so we simply say:
+
+\defCWEBmacro \CEE/{{\mc C\spacefactor1000}}
+\defCWEBmacro \UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\defCWEBmacro \TEX/{\TeX}
+\defCWEBmacro\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\defCWEBmacro \Cee{\CEE/} % for backward compatibility
+
+%D \macros{\ }{}
+%D
+%D Now we come to the real work: the short commands that make
+%D up the typography.
+%D
+%D \CWEBquote italic type for identifiers.
+
+\defCWEBmacro\\#1%
+ {\leavevmode\hbox{\it#1\/\kern.05em}}
+
+%D \macros{\string|}{}
+%D
+%D \CWEBquote one letter identifiers look better this way.
+
+\defCWEBmacro\|#1%
+ {\leavevmode\hbox{$#1$}}
+
+%D \macros{\string\&}{}
+%D
+%D \CWEBquote boldface type for reserved words.
+
+\defCWEBmacro\&#1%
+ {\leavevmode
+ \hbox
+ {\def\_%
+ {\kern.04em
+ \vbox{\hrule width.3em height .06\CWEBpt}% .6pt}%
+ \kern.08em}%
+ \bf#1\/\kern.05em}}
+
+%D \macros{.}{}
+%D
+%D Here we use the previously saved period. This macro
+%D takes care of special characters in strings.
+
+\defCWEBmacro\.#1%
+ {\leavevmode
+ \hbox
+ {\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+
+%D \macros{)}{}
+%D
+%D Some discretionary hack.
+
+\defCWEBmacro\)%
+ {\discretionary{\hbox{\tentex\BS}}{}{}}
+
+%D \macros{AT}{}
+%D
+%D \CWEBquote at sign for control text (not needed in versions
+%D $>=$ 2.9).
+
+\defCWEBmacro\AT{@}
+
+%D \macros{ATL,postATL,NOATL}{}
+%D
+%D A two step macro that handles whatever.
+
+\defCWEBmacro\ATL%
+ {\par
+ \noindent
+ \bgroup
+ \catcode`\_=12
+ \postATL}
+
+\defCWEBmacro\postATL#1 #2 %
+ {\bf letter \\{\uppercase{\char"#1}} tangles as \tentex "#2"%
+ \egroup
+ \par}
+
+\defCWEBmacro\noATL#1 #2 %
+ {}
+
+%D \macros{noatl}{}
+%D
+%D \CWEBquote suppress output from \type{@l}.
+
+\defCWEBmacro\noatl%
+ {\let\ATL=\noATL}
+
+% \defCWEBmacro\ATH%
+% {\X\kern-.5em:Preprocessor definitions\X}
+
+%D \macros{PB}
+%D
+%D \CWEBquote hook for program brackets {\tttf\string|...\string|}
+%D in TeX part or section name.
+
+\defCWEBmacro\PB%
+ {\relax}
+
+% \chardef\AM = `\& % ampersand character in a string
+% \chardef\BS = `\\ % backslash in a string
+% \chardef\LB = `\{ % left brace in a string
+% \chardef\RB = `\} % right brace in a string
+% \chardef\TL = `\~ % tilde in a string
+% \chardef\UL = `\_ % underline character in a string
+% \chardef\CF = `\^ % circumflex character in a string
+
+\defCWEBmacro\AM {\char`\&} % ampersand character in a string
+\defCWEBmacro\BS {\char`\\} % backslash in a string
+\defCWEBmacro\LB {\char`\{} % left brace in a string
+\defCWEBmacro\RB {\char`\}} % right brace in a string
+\defCWEBmacro\TL {\char`\~} % tilde in a string
+\defCWEBmacro\UL {\char`\_} % underline character in a string
+\defCWEBmacro\CF {\char`\^} % circumflex character in a string
+
+\defCWEBmacro\SP {{\tt\char`\ }} % (visible) space in a string
+
+% \newbox\PPbox \setbox\PPbox=\hbox
+% {\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+% \newbox\MMbox \setbox\MMbox=\hbox
+% {\kern.5pt\raise1pt\hbox{\sevensy\char0\kern-1pt\char0}\kern.5pt}
+% \newbox\MGbox \setbox\MGbox=\hbox % symbol for ->
+% {\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+% \newbox\MODbox \setbox\MODbox=\hbox
+% {\eightrm\%}
+%
+% \def\PP {\copy\PPbox}
+% \def\MM {\copy\MMbox}
+% \def\MG {\copy\MGbox}
+% \def\MOD {\mathbin{\copy\MODbox}}
+
+\defCWEBmacro\PP% symbol for ++
+ {\kern.05\CWEBpt
+ \raise.1\CWEBpt\hbox{\sevenrm+\kern-.1\CWEBpt+}%
+ \kern.05\CWEBpt}
+
+\defCWEBmacro\MM%
+ {\kern.05\CWEBpt
+ \raise.1\CWEBpt\hbox{\sevensy\char0\kern-.1\CWEBpt\char0}%
+ \kern.05\CWEBpt}
+
+\defCWEBmacro\MG%
+ {\kern-.2\CWEBpt
+ \lower.3\CWEBpt\hbox{\teni\char'176}%
+ \kern .1\CWEBpt}
+
+\defCWEBmacro\MRL#1%
+ {\mathrel{\let\K==#1}}
+
+% \def\MRL#1%
+% {\KK#1}
+% \def\KK#1#2%
+% {\buildrel\;#1\over{#2}}
+
+\letCWEBmacro\GG = \gg
+\letCWEBmacro\LL = \ll
+\letCWEBmacro\NULL = \Lambda
+
+% \mathchardef\AND = "2026 % bitwise and; also \& (unary operator)
+
+\defCWEBmacro\AND% redefines itself (funny)
+ {\mathchardef\AND="2026 \AND} % bitwise and; also \& (unary operator)
+
+\letCWEBmacro\OR = \mid % bitwise or
+\letCWEBmacro\XOR = \oplus % bitwise exclusive or
+\defCWEBmacro\CM {{\sim}} % bitwise complement
+\defCWEBmacro\MOD {\mathbin{\eightrm\%}}
+\defCWEBmacro\DC {\kern.1em{::}\kern.1em} % symbol for ::
+\defCWEBmacro\PA {\mathbin{.*}} % symbol for .*
+\defCWEBmacro\MGA {\mathbin{\MG*}} % symbol for ->*
+\defCWEBmacro\this {\&{this}}
+
+% \newbox \bak % backspace one em
+% \newbox \bakk % backspace two ems
+%
+% \setbox\bak =\hbox to -1em{}
+% \setbox\bakk=\hbox to -2em{}
+
+\newcount\CWEBind % current indentation in ems
+
+\defCWEBmacro\1% indent one more notch
+ {\global\advance\CWEBind by 1
+ \hangindent\CWEBind em}
+
+\defCWEBmacro\2% indent one less notch
+ {\global\advance\CWEBind by -1 }
+
+\defCWEBmacro\3#1% optional break within a statement
+ {\hfil
+ \penalty#10
+ \hfilneg}
+
+\defCWEBmacro\4% backspace one notch
+ {\hbox to -1em{}}
+
+\defCWEBmacro\5% optional break
+ {\hfil
+ \penalty-1
+ \hfilneg
+ \kern2.5em
+ \hbox to -2em{}%
+ \ignorespaces}
+
+\defCWEBmacro\6% forced break
+ {\ifmmode
+ \else
+ \par
+ \hangindent\CWEBind em
+ \noindent
+ \kern\CWEBind em
+ \hbox to -2em{}%
+ \ignorespaces
+ \fi}
+
+\defCWEBmacro\7% forced break and a little extra space
+ {\Y
+ \6}
+
+\defCWEBmacro\8% no indentation
+ {\hskip-\CWEBind em
+ \hskip 2em}
+
+\defCWEBmacro\9#1%
+ {}
+
+\newcount\gdepth % depth of current major group, plus one
+\newcount\secpagedepth
+\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1
+
+% \newtoks\gtitle % title of current major group
+% \newskip\intersecskip
+% \intersecskip=12pt minus 3pt % space between sections
+
+% \let\yskip=\smallskip
+
+\defCWEBmacro\?%
+ {\mathrel?}
+
+% \def\note#1#2.%
+% {\Y\noindent
+% {\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}}
+
+\defCWEBmacro\lapstar%
+ {\rlap{*}}
+
+% \def\stsec%
+% {\rightskip=0pt % get out of C mode (cf. \B)
+% \sfcode`;=1500
+% \pretolerance 200
+% \hyphenpenalty 50
+% \exhyphenpenalty 50
+% \noindent{\let\*=\lapstar\bf\secstar.\quad}}
+%
+% \let\startsection=\stsec
+
+\defCWEBmacro\defin#1%
+ {\global\advance\CWEBind by 2 \1\&{#1 } } % begin `define' or `format'
+
+% \def\A% xref for doubly defined section name
+% {\note{See also section}}
+%
+% \def\As% xref for multiply defined section name
+% {\note{See also sections}}
+
+\defCWEBmacro\B%
+ {\rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\CWEBind=2 \1\ \unskip}
+
+\defCWEBmacro\C#1%
+ {\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+
+% \let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+
+\defCWEBmacro\SHC#1%
+ {\5\5\quad$//\,${\cmntfont#1}}
+
+% \def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+% \def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+
+\defCWEBmacro\D% macro definition
+ {\defin{\#define}}
+
+\letCWEBmacro\E=\equiv % equivalence sign
+
+% \def\ET% conjunction between two section numbers
+% { and~}
+%
+% \def\ETs% conjunction between the last two of several section numbers
+% {, and~}
+
+\defCWEBmacro\F% format definition
+ {\defin{format}}
+
+\letCWEBmacro\G = \ge % greater than or equal sign
+
+% \H is long Hungarian umlaut accent
+
+\letCWEBmacro\I = \ne % unequal sign
+
+\defCWEBmacro\J% TANGLE's join operation
+ {\.{@\&}}
+
+% \let\K== % assignment operator
+
+\letCWEBmacro\K = \leftarrow % "honest" alternative to standard assignment operator
+
+% \L is Polish letter suppressed-L
+
+% \outer\def\M#1%
+% {\MN{#1}%
+% \ifon
+% \vfil
+% \penalty-100
+% \vfilneg % beginning of section
+% \vskip\intersecskip
+% \startsection
+% \ignorespaces}
+%
+% \outer\def\N#1#2#3.%
+% {\gdepth=#1%
+% \gtitle={#3}%
+% \MN{#2}% beginning of starred section
+% \ifon
+% \ifnum#1<\secpagedepth
+% \vfil
+% \eject % force page break if depth is small
+% \else
+% \vfil
+% \penalty-100
+% \vfilneg
+% \vskip\intersecskip
+% \fi
+% \fi
+% \message{*\secno}% progress report
+% \edef\next%
+% {\write\cont % write to contents file
+% {\ZZ{#3}{#1}{\secno}{\noexpand\the\pageno}}}%
+% \next % \ZZ{title}{depth}{sec}{page}
+% \ifon
+% \startsection
+% {\bf#3.\quad}%
+% \ignorespaces}
+%
+% \def\MN#1%
+% {\par % common code for \M, \N
+% {\xdef\secstar{#1}%
+% \let\*=\empty
+% \xdef\secno{#1}}% remove \* from section name
+% \ifx\secno\secstar
+% \onmaybe
+% \else
+% \ontrue
+% \fi
+% \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}}
+%
+% each \mark is {section reference or null}{depth plus 1}{group title}
+
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+
+\defCWEBmacro\Q {\note{This code is cited in section}} % xref for mention of a section
+\defCWEBmacro\Qs {\note{This code is cited in sections}} % xref for mentions of a section
+
+% \S is section sign
+
+\defCWEBmacro\T#1%
+ {\leavevmode % octal, hex or decimal constant
+ \hbox
+ {$\def\?{\kern.2em}%
+ \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct
+ \let\^=\hex
+ {#1}$}}
+
+\defCWEBmacro\U {\note{This code is used in section}} % xref for use of a section
+\defCWEBmacro\Us {\note{This code is used in sections}} % xref for uses of a section
+
+\letCWEBmacro\R = \lnot % logical not
+\letCWEBmacro\V = \lor % logical or
+\letCWEBmacro\W = \land % logical and
+
+% defined later on
+%
+% \def\X#1:#2\X%
+% {\ifmmode
+% \gdef\XX{\null$\null}%
+% \else
+% \gdef\XX{}%
+% \fi % section name
+% \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX}
+
+\unprotect
+
+\def\theCWEByskip {\blank[\v!small]}
+\def\theCWEBvskip {\blank[\v!big]}
+
+\protect
+
+\defCWEBmacro\Y%
+ {\par
+ \yskip}
+
+\defCWEBmacro\yskip%
+ {\theCWEByskip}
+
+\letCWEBmacro\Z = \le
+% \letCWEBmacro\ZZ = \let % now you can \write the control sequence \ZZ
+\letCWEBmacro\* = *
+
+\defCWEBmacro\oct%
+ {\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}
+
+\defCWEBmacro\hex%
+ {\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}}
+
+\defCWEBmacro\vb#1%
+ {\leavevmode
+ \hbox
+ {\kern.2\CWEBpt
+ \vrule
+ \vtop
+ {\vbox
+ {\hrule
+ \hbox{\strut\kern.2\CWEBpt\.{#1}\kern.2\CWEBpt}}
+ \hrule}%
+ \vrule
+ \kern.2\CWEBpt}} % verbatim string
+
+\def\onmaybe%
+ {\let\ifon=\maybe}
+
+\let\maybe=\iftrue
+
+\newif\ifon
+
+% \newif\iftitle
+% \newif\ifpagesaved
+%
+% \def\lheader%
+% {\mainfont
+% \the\pageno
+% \eightrm
+% \qquad
+% \grouptitle
+% \hfill
+% \title
+% \qquad
+% \mainfont
+% \topsecno} % top line on left-hand pages
+%
+% \def\rheader%
+% {\mainfont
+% \topsecno
+% \eightrm
+% \qquad
+% \title
+% \hfill
+% \grouptitle
+% \qquad
+% \mainfont
+% \the\pageno} % top line on right-hand pages
+%
+% \def\grouptitle
+% {\let\i=I
+% \let\j=J
+% \uppercase\expandafter{\expandafter\takethree\topmark}}
+%
+% \def\topsecno%
+% {\expandafter\takeone\topmark}
+%
+% \def\takeone #1#2#3{#1}
+% \def\taketwo #1#2#3{#2}
+% \def\takethree #1#2#3{#3}
+%
+% \def\nullsec%
+% {\eightrm
+% \kern-2em} % the \kern-2em cancels \qquad in headers
+%
+% \let\page=\pagebody % \def\page {\box255 }
+% \raggedbottom % \normalbottom % faster, but loses plain TeX footnotes
+%
+% \def\normaloutput#1#2#3%
+% {\shipout\vbox
+% {\ifodd
+% \pageno
+% \hoffset=\pageshift
+% \fi
+% \vbox to \fullpageheight
+% {\iftitle
+% \global\titlefalse
+% \else
+% \hbox to \pagewidth
+% {\vbox to 10pt{}%
+% \ifodd\pageno #3\else#2\fi}
+% \fi
+% \vfill#1}} % parameter #1 is the page itself
+% \global\advance\pageno by 1}
+%
+% \gtitle={\.{CWEB} output} % this running head is reset by starred sections
+%
+% \mark{\noexpand\nullsec0{\the\gtitle}}
+%
+% \def\title%
+% {\expandafter\uppercase\expandafter{\jobname}}
+%
+% \def\topofcontents%
+% {\centerline{\titlefont\title}
+% \vskip.7in
+% \vfill} % this material will start the table of contents page
+
+\def\botofcontents%
+ {\vfill
+ \centerline{\covernote}} % this material will end the table of contents page
+
+\def\covernote%
+ {}
+
+% some leftover
+
+\defCWEBmacro\contentspagenumber{0} % default page number for table of contents
+
+% \newdimen\pagewidth \pagewidth = 158mm % the width of each page
+% \newdimen\pageheight \pageheight = 223mm % the height of each page
+% \newdimen\fullpageheight \fullpageheight = 240mm % page height including headlines
+% \newdimen\pageshift \pageshift = 0in % shift righthand pages wrt lefthand ones
+%
+% \def\magnify#1%
+% {\mag=#1
+% \pagewidth=6.5truein
+% \pageheight=8.7truein
+% \fullpageheight=9truein
+% \setpage}
+%
+% \def\setpage%
+% {\hsize\pagewidth
+% \vsize\pageheight} % use after changing page size
+%
+% \def\contentsfile {\jobname.toc} % file that gets table of contents info
+% \def\readcontents {\input \contentsfile}
+% \def\readindex {\input \jobname.idx}
+% \def\readsections {\input \jobname.scn}
+%
+% \newwrite\cont
+% \output{\setbox0=\page % the first page is garbage
+% \openout\cont=\contentsfile
+% \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+% \global\output{\normaloutput\page\lheader\rheader}}
+% \setpage
+% \vbox to \vsize{} % the first \topmark won't be null
+
+\defCWEBdummy\magnify#1% magnify the page
+ {}
+
+\defCWEBmacro\ch%
+ {\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+
+% \newbox\sbox % saved box preceding the index
+% \newbox\lbox % lefthand column in the index
+%
+% \def\inx%
+% {\par\vskip6pt plus 1fil % we are beginning the index
+% \def\page{\box255 }
+% \normalbottom
+% \write\cont{} % ensure that the contents file isn't empty
+% \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+% \closeout\cont % the contents information has been fully gathered
+% \output
+% {\ifpagesaved
+% \normaloutput{\box\sbox}\lheader\rheader
+% \fi
+% \global\setbox\sbox=\page
+% \global\pagesavedtrue}
+% \pagesavedfalse
+% \eject % eject the page-so-far and predecessors
+% \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+% \vsize=\pageheight
+% \advance\vsize by -\ht\sbox % the remaining height
+% \hsize=.5\pagewidth
+% \advance\hsize by -10pt
+% % column width for the index (20pt between cols)
+% \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+% \def\lr{L} % this tells whether the left or right column is next
+% \output
+% {\if L\lr
+% \global\setbox\lbox=\page
+% \gdef\lr{R}
+% \else
+% \normaloutput
+% {\vbox to\pageheight
+% {\box\sbox
+% \vss
+% \hbox to\pagewidth{\box\lbox\hfil\page}}}
+% \lheader
+% \rheader
+% \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+% \message{Index:}
+% \parskip 0pt plus .5pt
+% \outer\def\I##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+% \def\[##1]{$\underline{##1}$} % underlined index item
+% \rm
+% \rightskip0pt plus 2.5em
+% \tolerance 10000
+% \let\*=\lapstar
+% \hyphenpenalty 10000
+% \parindent0pt
+% \readindex}
+%
+% \def\fin%
+% {\par\vfill\eject % this is done when we are ending the index
+% \ifpagesaved\null\vfill\eject\fi % output a null index column
+% \if L\lr\else\null\vfill\eject\fi % finish the current page
+% \parfillskip 0pt plus 1fil
+% \def\grouptitle{NAMES OF THE SECTIONS}
+% \let\topsecno=\nullsec
+% \message{Section names:}
+% \output={\normaloutput\page\lheader\rheader}
+% \setpage
+% \def\note##1##2.{\quad{\eightrm##1~##2.}}
+% \def\Q{\note{Cited in section}} % crossref for mention of a section
+% \def\Qs{\note{Cited in sections}} % crossref for mentions of a section
+% \def\U{\note{Used in section}} % crossref for use of a section
+% \def\Us{\note{Used in sections}} % crossref for uses of a section
+% \def\I{\par\hangindent 2em}\let\*=*
+% \readsections}
+%
+% \def\con%
+% {\par\vfill\eject % finish the section names
+% %\ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+% \rightskip = 0pt
+% \hyphenpenalty = 50
+% \tolerance = 200
+% \setpage
+% \output={\normaloutput\page\lheader\rheader}
+% \titletrue % prepare to output the table of contents
+% \pageno=\contentspagenumber
+% \def\grouptitle{TABLE OF CONTENTS}
+% \message{Table of contents:}
+% \topofcontents
+% \line{\hfil Section\hbox to3em{\hss Page}}
+% \let\ZZ=\contentsline
+% \readcontents\relax % read the contents info
+% \botofcontents
+% \end} % print the contents page(s) and terminate
+%
+% \def\contentsline#1#2#3#4%
+% {\ifnum#2=0
+% \smallbreak
+% \fi
+% \line{\consetup{#2}#1
+% \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to3em{\hss#4}}}
+%
+
+\defCWEBmacro\consetup#1%
+ {\ifcase#1 \bf % depth -1 (@**)
+ \or % depth 0 (@*)
+ \or \hskip2em % depth 1 (@*1)
+ \or \hskip4em % depth 2 (@*2)
+ \or \hskip6em % depth 3 (@*3)
+ \or \hskip8em % depth 4 (@*4)
+ \or \hskip10em % depth 5 (@*5)
+ \else \hskip12em
+ \fi} % depth 6 or more
+
+\defCWEBdummy \inx {} % index
+\defCWEBdummy \fin {} % finish
+\defCWEBdummy \con {} % table of contents and finish
+
+\defCWEBdummy \noinx {} % no indexes or table of contents
+\defCWEBdummy \nosecs {} % no index of section names or table of contents
+\defCWEBdummy \nocon {} % no table of contents
+
+\defCWEBmacro\,%
+ {\relax
+ \ifmmode
+ \mskip\thinmuskip
+ \else
+ \thinspace
+ \fi}
+
+% \def\noinx%
+% {\let\inx=\end}
+%
+% \def\nosecs%
+% {\let\FIN=\fin
+% \def\fin%
+% {\let\parfillskip=\end
+% \FIN}}
+%
+% \def\nocon%
+% {\let\con=\end}
+%
+% \newcount\twodigits
+%
+% \def\hours%
+% {\twodigits=\time
+% \divide\twodigits by 60
+% \printtwodigits
+% \multiply\twodigits by -60
+% \advance\twodigits by \time
+% :\printtwodigits}
+%
+% \def\gobbleone1{}
+%
+% \def\printtwodigits%
+% {\advance\twodigits by 100
+% \expandafter\gobbleone\number\twodigits
+% \advance\twodigits by -100 }
+%
+% \def\today%
+% {\ifcase\month
+% \or January\or February\or March\or April\or May\or June%
+% \or July\or August\or September\or October\or November\or December%
+% \fi
+% \space
+% \number\day, \number\year}
+%
+% \def\datethis%
+% {\def\startsection%
+% {\leftline{\sc\today\ at \hours}
+% \bigskip
+% \let\startsection=\stsec
+% \stsec}}
+%
+% \def\datecontentspage%
+% {\def\topofcontents%
+% {\leftline{\sc\today\ at \hours}
+% \bigskip
+% \centerline{\titlefont\title}
+% \vfill}}
+
+\defCWEBdummy\datethis {} % say `\datethis' in limbo, to get your listing timestamped before section 1
+\defCWEBdummy\datecontentspage {} % timestamps the contents page
+
+\defCWEBmacro\TeX%
+ {{\ifmmode\it\fi
+ \leavevmode
+ \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+
+% alternative implementation
+
+\newif\ifCWEBnotes
+
+\defCWEBmacro\Q {\CWEBnotesfalse \note{This code is cited in section}} % xref for mention of a section
+\defCWEBmacro\Qs {\CWEBnotestrue \note{This code is cited in sections}} % xref for mentions of a section
+
+\defCWEBmacro\U {\CWEBnotesfalse \note{This code is used in section}} % xref for use of a section
+\defCWEBmacro\Us {\CWEBnotestrue \note{This code is used in sections}} % xref for uses of a section
+
+\defCWEBmacro\A {\CWEBnotesfalse \note{See also section}} % xref for doubly defined section name
+\defCWEBmacro\As {\CWEBnotestrue \note{See also sections}} % xref for multiply defined section name
+
+\defCWEBmacro\ET% conjunction between two section numbers
+ { and~}
+
+\defCWEBmacro\ETs% conjunction between the last two of several section numbers
+ {, and~}
+
+%\def\processCWEBsectionnumbers[#1]%
+% {\bgroup
+% \def\CWEBcomma%
+% {\def\CWEBcomma{, }}%
+% \def\docommand##1%
+% {\bgroup
+% \def\[####1]{####1}%
+% \xdef\CWEBreference{##1}%
+% \egroup
+% \CWEBcomma{\naar{\donottest{##1}}[web:\CWEBreference]}}%
+% \processcommalist[{#1}]\docommand
+% \egroup}
+
+% \def\processCWEBsectionnumbers[#1]%
+% {\bgroup
+% \def\CWEBcomma%
+% {\def\CWEBcomma{, }}%
+% \def\docommand##1%
+% {\bgroup
+% \def\(####1){####1}%
+% \xdef\CWEBreference{##1}%
+% \egroup
+% \CWEBcomma
+% {\localcolortrue\naar{\donottest{##1}}[web:\CWEBreference]}}%
+% \bgroup
+% \def\[##1]{\(##1)}\let\(=\relax\xdef\CWEBreferences{#1}%
+% \egroup
+% \unexpanded\def\(##1){\[##1]}%
+% \processcommacommand[\CWEBreferences]\docommand
+% \egroup}
+
+\def\processCWEBsectionnumbers[#1]%
+ {\bgroup
+ \def\CWEBcomma%
+ {\def\CWEBcomma{, }}%
+ \def\docommand##1%
+ {\bgroup
+ \def\[####1]{####1}%
+ \xdef\CWEBreference{##1}%
+ \egroup
+ \CWEBcomma{\localcolortrue\goto{\donottest{##1}}[web:\CWEBreference]}}%
+ \processlist{(}{)}{,}\docommand(#1)
+ \egroup}
+
+\def\processCWEBsectionnotes%
+ {\catcode`\s=12
+ \doprocessCWEBsectionnotes}
+
+\def\doprocessCWEBsectionnotes#1.%
+ {\ifCWEBnotes
+ \def\next##1\ET##2##3.%
+ {\processCWEBsectionnumbers[##1]%
+ \if##2s%
+ {, and~\goto{##3}[web:##3]}%
+ \else
+ { and~\goto{##2##3}[web:##2##3]}%
+ \fi}%
+ \next#1.%
+ \else
+ \goto{#1}[web:#1]%
+ \fi
+ \afterCWEBnote % inside group!
+ \egroup}
+
+\let\afterCWEBnote=\relax
+
+\defCWEBmacro\note#1%
+ {\bgroup
+ \Y\noindent
+ \def\afterCWEBnote{\par}%
+ \hangindent2em
+ %\baselineskip10pt
+ \eightrm#1~\processCWEBsectionnotes}
+
+\def\oldCWEBmacroX#1:#2\X% original
+ {\ifmmode
+ \gdef\XX{\null$\null}%
+ \else
+ \gdef\XX{}%
+ \fi % section name
+ \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX}
+
+\defCWEBmacro\ATH%
+ {\oldCWEBmacroX\kern-.5em:Preprocessor definitions\X}
+
+\def\newCWEBmacroX#1:#2\X% original
+ {\ifmmode
+ \gdef\XX{\null$\null}%
+ \else
+ \gdef\XX{}%
+ \fi % section name
+ \XX$\langle\,$%
+ {#2\eightrm\kern.5em\processCWEBsectionnumbers[{#1}]}%
+ $\,\rangle$\XX}
+
+\defCWEBmacro\X#1:#2\X%
+ {\newCWEBmacroX#1:#2\X}
+
+\definemarking[CWEBfilename]
+\definemarking[CWEBsectiontitle]
+\definemarking[CWEBsectionnumber]
+\definemarking[CWEBsectiondepth]
+
+\defCWEBmacro\M#1%
+ {\MN{#1}%
+ \ifon
+ \vfil
+ \penalty-100
+ \vfilneg % beginning of section
+ \theCWEBvskip
+ \startsection
+ \pagereference[web:#1]%
+ \expanded{\marking[CWEBsectionnumber]{\secno}}%
+ \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}%
+ \ignorespaces}
+
+\defCWEBmacro\N#1#2#3.%
+ {\gdepth=#1%
+ \MN{#2}% beginning of starred section
+ \ifon
+ \ifnum#1<\secpagedepth
+ \vfil
+ \eject % force page break if depth is small
+ \else
+ \vfil
+ \penalty-100
+ \vfilneg
+ \theCWEBvskip
+ \fi
+ \fi
+ \message{*\secno}% progress report
+ \makesectionformat % context
+ \defconvertedargument\ascii{#3}%
+ \edef\next%
+ {\write\CWEBcont % write to contents file
+ {\string\ZZ{\ascii}{#1}{\secno}%
+ {\sectionformat::\noexpand\userfolio}{\noexpand\realfolio}}}%
+ \next % \ZZ{title}{depth}{sec}{page}
+ \ifon
+ \startsection
+ \pagereference[web:#2]%
+ \marking[CWEBsectiontitle] {#3}%
+ \expanded{\marking[CWEBsectionnumber]{\secno}}%
+ \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}%
+ {\bf#3.\quad}%
+ \ignorespaces}
+
+\defCWEBmacro\MN#1%
+ {\par % common code for \M, \N
+ {\xdef\secstar{#1}%
+ \let\*=\empty
+ \xdef\secno{#1}}% remove \* from section name
+ \ifx\secno\secstar
+ \onmaybe
+ \else
+ \ontrue
+ \fi}
+
+\newif\iflinktoCWEBfile
+
+\def\setCWEBlinkfile#1%
+ {\linktoCWEBfiletrue
+ \def\otherCWEBfile{#1}}
+
+\unprotect
+
+\def\gotoCWEBsection#1[#2]%
+ {\iflinktoCWEBfile
+ \bgroup
+ \setupinteraction[\c!color=,\c!style=]%
+ \let\savedreferenceprefix=\referenceprefix
+ \localcolortrue
+ \goto{#1}[\otherCWEBfile::\savedreferenceprefix web:#2]%
+ \egroup
+ \else
+ #1%
+ \fi}
+
+\protect
+
+\defCWEBmacro\startsection%
+ {\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500
+ \pretolerance 200
+ \hyphenpenalty 50
+ \exhyphenpenalty 50
+ \noindent
+ \bgroup
+ \let\*=\lapstar
+ \gotoCWEBsection{\bf\secstar.\quad}[\secno]%
+ \egroup}
+
+\def\ignoreCWEBinput%
+ {\let\normalinput=\input
+ \def\input ##1 %
+ {\let\input=\normalinput}}
+
+\def\loadCWEBmacros#1%
+ {\let\oldN=\N
+ \def\N{\bgroup\setbox0=\vbox\bgroup\endinput}%
+ \ignoreCWEBinput
+ \ReadFile{#1.tex}%
+ \egroup\egroup
+ \let\N=\oldN}
+
+\def\resetCWEBcontext%
+ {\catcode`\|=12 % used in context discretionaries
+ \everypar{} % used for context indentation and floats
+ \parskip=0pt % no stretch between cweb paragraphs
+ \parindent=1em} % is related to cweb backspace etc
+
+\newwrite\CWEBcont
+
+\def\processCWEBsource #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \ignoreCWEBinput
+ \immediate\openout\CWEBcont=#1.toc
+ \write\CWEBcont{\noexpand\unprotect}
+ \message{Source:}
+ \marking[CWEBfilename]{#1}
+ \ReadFile{#1.tex}\relax
+ \write\CWEBcont{\noexpand\protect}
+ \closeout\CWEBcont
+ \par
+ \egroup}
+
+\def\resetCWEBindexentry%
+ {\xdef\currentCWEBindexentry{}}
+
+\def\showCWEBindexentry#1% can be redefined
+ {\theCWEBvskip
+ \vskip3\lineheight
+ \goodbreak
+ \vskip-3\lineheight
+ {\pagereference[web:#1]\bf#1}%
+ \theCWEBvskip}
+
+\def\checkCWEBindexentry#1%
+ {\bgroup
+ \def\\##1{##1}% a dummy that also removes the {}
+ \def\|##1{##1}% another dummy
+ \def\.##1{*##1}% and another (the typewriter one)
+ \def\&##1{##1}% and a last one
+ \def\9##1{##1}% hold this one
+ \catcode`*=11
+ \expandafter\def\expandafter\entry\expandafter{#1}%
+ \defconvertedcommand\ascii\entry
+ \expanded{\FINDFIRSTCHARACTER{\ascii}}%
+ \doifnot{\currentCWEBindexentry}{\firstcharacter}
+ {\doifnot{\firstcharacter}{*} % signal for \firstbunch
+ {\global\let\currentCWEBindexentry=\firstcharacter
+ \showCWEBindexentry{\currentCWEBindexentry}}}%
+ \egroup}
+
+\def\theCWEBbeforeindex {\startcolumns}
+\def\theCWEBafterindex {\stopcolumns}
+
+\def\processCWEBindex #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \resetCWEBindexentry
+ \def\I##1, %
+ {\par
+ \checkCWEBindexentry{##1}%
+ \hangindent2em
+ \noindent##1:\kern1em%
+ \def\next####1.%
+ {\processCWEBsectionnumbers[{####1}]}%
+ \next}%
+ \def\[##1]%
+ {$\underline{##1}$}%
+ \let\*=\lapstar
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+% \parskip 0pt plus .5pt
+ \rightskip0pt plus 2.5em
+ \tolerance 10000
+ \hyphenpenalty 10000
+ \parindent0pt
+ \message{Index:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {index}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \theCWEBbeforeindex
+ \ReadFile{#1.idx}\relax
+ \theCWEBafterindex
+ \par
+ \egroup}
+
+\def\processCWEBsections #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \loadCWEBmacros{#1}
+ \parfillskip = 0pt plus 1fil
+ \parindent = 0pt
+ \let\topsecno=\nullsec
+ \def\note##1%
+ {\quad
+ \bgroup
+ \eightrm
+ ##1~\processCWEBsectionnotes}
+ \def\Q {\CWEBnotesfalse \note{Cited in section}} % crossref for mention of a section
+ \def\Qs{\CWEBnotestrue \note{Cited in sections}} % crossref for mentions of a section
+ \def\U {\CWEBnotesfalse \note{Used in section}} % crossref for use of a section
+ \def\Us{\CWEBnotestrue \note{Used in sections}} % crossref for uses of a section
+ \def\I {\par\hangindent 2em}%
+ \let\*=*
+ \message{Section names:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {sections}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \ReadFile{#1.scn}\relax
+ \par
+ \botofcontents
+ \par
+ \egroup}
+
+\def\processCWEBcontents #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \loadCWEBmacros{#1}
+ \rightskip = 0pt
+ \hyphenpenalty = 50
+ \tolerance = 200
+ \parindent = 0pt
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \let\ZZ=\contentsline
+ \message{Table of contents:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {table of contents}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \ReadFile{#1.toc}\relax
+ \par
+ \egroup}
+
+\defCWEBmacro\contentsline#1#2#3#4#5%
+ {\ifnum#2=0
+ \smallbreak
+ \fi
+ \line{\consetup{#2}#1
+ \rm
+ \leaders\hbox to .5em{.\hfil}\hfil\
+ {\localcolortrue\goto{#3}[web:#3]}% below: \gotorealpage ? should be changed
+ \hbox to3em{\localcolortrue\hss\gotorealpage{}{}{#5}{\translatednumber[#4]\presetgoto}}}}
+
+%D A last hack, needed because a file can overload of the
+%D above. (Some day: a check like \type{\ifx#1\CWEBdefined}.)
+
+\def\outer#1#2%
+ {\ifx#2\undefined
+ \expandafter#1\expandafter#2%
+ \else
+ \expandafter#1\expandafter\ThrowAway
+ \fi}
+
+\endinput
diff --git a/tex/context/modules/mkii/m-database.mkii b/tex/context/modules/mkii/m-database.mkii
new file mode 100644
index 000000000..abb67986e
--- /dev/null
+++ b/tex/context/modules/mkii/m-database.mkii
@@ -0,0 +1,420 @@
+%D \module
+%D [ file=m-database,
+%D version=2006.04.23,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Database Thingies,
+%D author=Hans Hagen\& Taco Hoekwater,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+% % % to be added to mult-* files
+%
+% % % todo: \dontcollectseparatedlist via k/v
+
+\definesystemvariable{ls}
+
+\def\c!first {first}
+\def\c!last {last}
+\def\c!quotechar {quotechar}
+
+\let\@NX\noexpand
+
+%D {processquotedlist}
+%D
+%D An even more general list processing macro is the
+%D following one:
+%D
+%D \starttyping
+%D \processquotedlist{beginsym}{endsym}{separator}\docommand list
+%D \stoptyping
+%D
+%D This one supports arbitrary open and close symbols as well
+%D as user defined separators.
+%D
+%D \starttyping
+%D \processquotedlist(){,}{"}\docommand(a=>b=>c=>d)
+%D \stoptyping
+
+\def\processquotedlist#1#2#3#4#5%
+ {\def\csvquotechar{#4}%
+ \edef\doconvertcsvquoteditem#4##1#4##2%
+ {\@NX\ifx##2#3%
+ \let\@NX\next\@NX\doconvertcsvlist
+ \def\@NX\arg{#3}%
+ \edef\@NX\temp{##1}%
+ \@NX\expanded{\@NX#5{\@NX\temp}}%
+ \@NX\else
+ \let\@NX\next\@NX\redoconvertcsvquoteditem
+ \def\@NX\arg{##1\@NX\csvquotechar}%
+ \@NX\fi
+ \@NX\expandafter\@NX\next\@NX\arg}%
+ \edef\redoconvertcsvquoteditem##1#4##2%
+ {\@NX\ifx##2#3%
+ \let\@NX\next\@NX\doconvertcsvlist
+ \def\@NX\arg{#3}%
+ \edef\@NX\temp{##1}%
+ \@NX\expanded{\@NX#5{\@NX\temp}}%
+ \@NX\else
+ \let\@NX\next\@NX\redoconvertcsvquoteditem
+ \def\@NX\arg{##1\@NX\csvquotechar}%
+ \@NX\fi
+ \@NX\expandafter\@NX\next\@NX\arg}%
+ \edef\doconvertcsvitem##1#3%
+ {\edef\@NX\temp{##1}%
+ \@NX\expanded{\@NX#5{\@NX\temp}}%
+ \@NX\doconvertcsvlist#3}%
+ \edef\doconvertcsvlist#3##1%
+ {\@NX\ifx##1\@NX#2%
+ \let\@NX\next \@NX\gobbleoneargument
+ \@NX\else\@NX\ifx##1#4%
+ \let\@NX\next \@NX\doconvertcsvquoteditem
+ \@NX\else
+ \let\@NX\next \@NX\doconvertcsvitem
+ \@NX\fi\@NX\fi \@NX\next##1}%
+ \doconvertcsvitem}
+
+\gdef\doprocessseparatedquoteditem#1%
+ {\appendseparatedlistparameter\c!left%
+ \appendseparatedlistcontent{#1}%
+ \appendseparatedlistparameter\c!right}
+
+% a version more robust with regard to {a a} b c d situations:
+
+\edef\detokenizedrelax{\detokenize{\relax}}
+
+\edef\processseplistseparator{\detokenize{,}}%
+
+\def\dodefineprocessseplist#1#2% separator \docommand
+ {\edef\processseplistseparator{\detokenize{#1}}%
+ \def\dodoprocessseplist##1##2#1%
+ {\edef\!!stringa{\detokenize{##1}}%
+ \ifx\detokenizedrelax\!!stringa
+ \expandafter\nodoprocessseplist
+ % \else\ifx\!!stringa#1%
+ \else\ifx\!!stringa\processseplistseparator
+ #2{}%
+ #2{##2}%
+ \expandafter\expandafter\expandafter\dodoprocessseplist
+ \else
+ #2{##1##2}%
+ \expandafter\expandafter\expandafter\dodoprocessseplist
+ \fi\fi}%
+ \def\doprocessseplist##1\relax
+ {\dodoprocessseplist##1#1\relax#1\relax\relax\end}}
+
+\def\nodoprocessseplist#1\end
+ {}
+
+\long\def\processseplist#1#2#3\relax raw version
+ {\dodefineprocessseplist{#1}{#2}%
+ \dodoprocessseplist#3#1\relax#1\relax\relax\end}
+
+% \dodefineprocessseplist{,}\test
+% \dodoprocessseplist{,}a,b,c\relax,\relax\relax\end
+% \doprocessseplista,b,c\relax
+
+% \def\test#1{[#1]}
+% \startlines
+% \processseplist{,}\test ,2,,\relax
+% \processseplist{,}\test ,,,44\relax
+% \processseplist{,}\test ,,33,44\relax
+% \processseplist{,}\test 11,,33,44\relax
+% \processseplist{,}\test 1,2,3,4\relax
+% \stoplines
+
+\newtoks\separatedlistdata
+
+\def\appendseparatedlistparameter#1%
+ {\@EAEAEA\appendtoks\csname\??ls\currentseparatedlist#1\endcsname\to\separatedlistdata}
+
+\def\appendseparatedlistcontent#1%
+ {\appendtoks#1\to\separatedlistdata}
+
+\def\flushseparatedlistdata
+ {\the\separatedlistdata
+ \separatedlistdata\emptytoks}
+
+\def\initializeseparatedlistdata
+ {\separatedlistdata{\egroup}}
+
+\def\dontcollectseparatedlist
+ {\def\dodoprocessseparatedfileline
+ {\the\separatedlistdata
+ \separatedlistdata\emptytoks
+ \doprocessseparatedfileline}%
+ \def\dodoprocessseparatedline
+ {\the\separatedlistdata
+ \separatedlistdata\emptytoks
+ \doprocessseparatedline}%
+ \let\flushseparatedlistdata\egroup
+ \let\initializeseparatedlistdata\donothing}
+
+\chardef\separatedlistmode\zerocount
+
+\def\setcurrentlistseparator
+ {\edef\currentlistseparator
+ {\executeifdefined
+ {\??ls::\csname\??ls\currentseparatedlist\c!separator\endcsname}%
+ {\csname\??ls\currentseparatedlist\c!separator\endcsname}}%
+ \doifvalue{\??ls\currentseparatedlist\c!separator}{tab}
+ {\catcode`\^^I=12\relax}%
+ \ifx\currentlistseparator\empty\def\currentlistseparator{,}\fi}
+
+\bgroup \catcode`\^^I=12
+ \setgvalue{\??ls::tab}{ }
+ \setgvalue{\??ls::space}{ }
+ \setgvalue{\??ls::comma}{,}
+\egroup
+
+\def\doprocessseparatedfileline
+ {\ifeof\scratchread
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!after\fi
+ \immediate\closein\scratchread
+ \expandafter\flushseparatedlistdata
+ \else\ifx\line\empty
+ % skip, can be comment
+ \read\scratchread to\line
+ \@EA\dodoprocessseparatedfileline
+ \else
+ \appendseparatedlistparameter{\ifcase\separatedlistmode\c!first\else\c!command\fi}%
+ \ifx\currentlistquotechar\empty%
+ \expandafter\doprocessseplist\line\relax
+ \else
+ \expanded{\processquotedlist{}{\noexpand\end}%
+ {\currentlistseparator}{\currentlistquotechar}%
+ \noexpand\doprocessseparatedquoteditem \line\currentlistseparator\noexpand\end}%
+ \fi
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!last\fi
+ \read\scratchread to\line
+ \@EAEAEA\dodoprocessseparatedfileline
+ \fi\fi}
+
+\def\dodoprocessseparatedfileline
+ {\doprocessseparatedfileline}
+
+\def\doprocessseparatedfile[#1][#2]%
+ {\bgroup
+ \edef\currentseparatedlist{#1}%
+ \doifdefined{\??ls\currentseparatedlist\c!command}{\chardef\separatedlistmode\plusone}%
+ \setcurrentlistseparator
+ \edef\currentlistquotechar{\csname\??ls\currentseparatedlist\c!quotechar\endcsname}%
+ \expandafter\dodefineprocessseplist\expandafter{\currentlistseparator}\doprocessseparateditem
+ \initializeseparatedlistdata
+ \directsetup{\currentseparatedlist:\executeifdefined{\??ls\currentseparatedlist\c!setups}\s!default}%
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!before\fi
+ \endlinechar\minusone
+ \ignorelines
+ \catcode`\#\@@comment
+ \immediate\openin\scratchread=#2\relax % todo: \doopenin
+ \read\scratchread to\line
+ \doprocessseparatedfileline}
+
+\def\dostartseparatedlist#1[#2]%
+ {\bgroup
+ \edef\currentseparatedlist{#2}%
+ \doifdefined{\??ls\currentseparatedlist\c!command}{\chardef\separatedlistmode\plusone}%
+ \obeylines
+ \let#1\relax
+ \def\separateslistend{#1}%
+ \setcurrentlistseparator
+ \edef\currentlistquotechar{\csname\??ls\currentseparatedlist\c!quotechar\endcsname}%
+ \expandafter\dodefineprocessseplist\expandafter{\currentlistseparator}\doprocessseparateditem
+ \directsetup{\currentseparatedlist:\executeifdefined{\??ls\currentseparatedlist\c!setups}\s!default}%
+ \initializeseparatedlistdata
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!before\fi
+ \dodostartseparatedlist}
+
+\def\redoprocessseparatedline#1%
+ {\def\!!stringa{#1}%
+ \ifx\!!stringa\separateslistend
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!after\fi
+ \expandafter\flushseparatedlistdata
+ \else%
+ \appendseparatedlistparameter{\ifcase\separatedlistmode\c!first\else\c!command\fi}%
+ \ifx\currentlistquotechar\empty%
+ \doprocessseplist#1\relax
+ \else%
+ \defconvertedargument\csvdata{#1}%
+ \expanded{\processquotedlist{}{\noexpand\end}%
+ {\currentlistseparator}{\currentlistquotechar}%
+ \noexpand\doprocessseparatedquoteditem \csvdata\currentlistseparator\noexpand\end}%
+ \fi
+ \ifcase\separatedlistmode\appendseparatedlistparameter\c!last\fi
+ \expandafter\dodoprocessseparatedline
+ \fi}
+
+\def\doprocessseparatedline
+ {\doifnextbgroupelse\xdoprocessseparatedline\ydoprocessseparatedline}
+
+\def\dodoprocessseparatedline
+ {\doprocessseparatedline}
+
+\def\doprocessseparateditem#1%
+ {\ifcase\separatedlistmode
+ \appendseparatedlistparameter\c!left
+ \appendseparatedlistcontent{#1}%
+ \appendseparatedlistparameter\c!right
+ \else
+ \appendseparatedlistcontent{{#1}}%
+ \fi}
+
+
+\bgroup \obeylines
+
+ \gdef\dodostartseparatedlist#1
+ {\doprocessseparatedline}
+
+ \gdef\xdoprocessseparatedline#1#2
+ {\redoprocessseparatedline{{{#1}}#2}}
+
+ \gdef\ydoprocessseparatedline#1
+ {\redoprocessseparatedline{#1}}
+
+\egroup
+
+\startsetups CSV:unix
+ \catcode`\#=\@@comment
+\stopsetups
+
+\def\defineseparatedlist
+ {\dodoubleempty\dodefineseparatedlist}
+
+\def\dodefineseparatedlist[#1][#2]%
+ {\setvalue{\e!start#1}{\expandafter\dostartseparatedlist\csname\e!stop#1\endcsname[#1]}%
+ \getparameters
+ [\??ls#1]
+ [\c!separator=,
+ \c!quotechar=,
+ \c!first=,
+ \c!left=,
+ \c!before=,
+ \c!right=,
+ \c!last=,
+ \c!after=,
+% \c!command=,
+ #2]}
+
+\def\setupseparatedlist
+ {\dodoubleempty\dosetupseparatedlist}
+
+\def\dosetupseparatedlist[#1]% [#2]
+ {\getparameter[\??ls#1]} % [#2]
+
+\def\startseparatedlist[#1]%
+ {\dostartseparatedlist\stopseparatedlist[#1]}
+
+\def\processseparatedfile
+ {\dodoubleargument\doprocessseparatedfile}
+
+\protect \doifnotmode{demo}{\endinput}
+
+\defineseparatedlist
+ [CSV]
+ [separator={,},
+ first=\bTR,last=\eTR,
+ left=\bTD,right=\eTD,
+ before=\bTABLE,after=\eTABLE]
+
+\startseparatedlist[CSV]
+a,b,c
+d,e,f
+\stopseparatedlist
+
+\startCSV
+a,b,c
+d,e,f
+\stopCSV
+
+\defineseparatedlist
+ [CSV]
+ [separator={,},
+ quotechar={"},
+ first=\NC,last=\NR,
+ left=,right=\NC,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate]
+
+\startCSV
+a,b,"c,d"
+d,"""",f
+\stopCSV
+
+\defineseparatedlist
+ [CSV]
+ [separator={ },
+ first=\NC,last=\NR,
+ left=,right=\NC,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate]
+
+\startCSV
+a b c
+d e f
+\stopCSV
+
+\defineseparatedlist
+ [CSV]
+ [setups=unix,
+ first=\NC,last=\NR,
+ left=,right=\NC,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate]
+
+% \startsetups CSV:unix
+% \catcode`\#=\@@comment
+% \stopsetups
+
+% %1,2,3
+% 1,2,3
+% # 4,5,6
+% 4,5,6
+
+\processseparatedfile[CSV][test.dat]
+
+\defineseparatedlist
+ [CSVX]
+ [command=\Whatever,
+ separator={,},
+ first=\bTR,last=\eTR,
+ left=\bTD,right=\eTD,
+ before=\bTABLE,after=\eTABLE]
+
+\def\Whatever#1#2#3{[#1][#2][#3]\endgraf}
+
+\startseparatedlist[CSVX]
+a,b,c
+d,e,f
+\stopseparatedlist
+
+\defineseparatedlist[CSV]
+ [separator=comma,
+ before=\bTABLE, after=\eTABLE,
+ first=\bTR, last=\eTR,
+ left=\bTD, right=\eTD]
+
+\startCSV
+a,b,c,č
+d,e,f,š
+\stopCSV
+
+\enableregime[utf]
+
+\defineseparatedlist[X][separator=X,left=(,right=),first=\endgraf,last=\endgraf]
+\defineseparatedlist[Y][separator=Y,left=(,right=),first=\endgraf,last=\endgraf]
+
+\startX
+aXb
+Xc
+čXš
+\stopX
+
+\startY
+aYb
+Yc
+čYš
+\stopY
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-dratex.mkii b/tex/context/modules/mkii/m-dratex.mkii
new file mode 100644
index 000000000..2b5f0be2a
--- /dev/null
+++ b/tex/context/modules/mkii/m-dratex.mkii
@@ -0,0 +1,21 @@
+%D \module
+%D [ file=m-dratex,
+%D version=2005.11.25,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\DRATEX\ Loading Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details
+
+\readfile{DraTex.sty}{}{\readfile{dratex.sty}{}{\endinput}}
+
+\letvalue{:NewCount}\newcount
+\letvalue{:NewDimen}\newdimen
+
+\readfile{AlDraTex.sty}{}{\readfile{aldratex.sty}{}{\endinput}}
+
+\endinput
diff --git a/tex/context/modules/mkii/m-edtsnc.mkii b/tex/context/modules/mkii/m-edtsnc.mkii
new file mode 100644
index 000000000..0f66893e8
--- /dev/null
+++ b/tex/context/modules/mkii/m-edtsnc.mkii
@@ -0,0 +1,207 @@
+%D \module
+%D [ file=m-editsnc,
+%D version=2003.12.23,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Editor Synchronization,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.edit for
+%C details.
+
+% \enablemode[demo]
+
+% This file is a variation of the file m-pdfsync. This time we do it
+% in a more abstract way and prepare ourselves for support in dvi
+% output.
+
+% \enableeditsync
+% \disableeditsync
+% \editsync
+% \editsynctext {string}
+% \editsyncnode {char}
+% \editsynctracemode [chardef: 0-4]
+
+\writestatus{editsync}{loading and enabling editor synchronization support}
+
+\unprotect % not really needed
+
+\ifx\pdfoutput\undefined
+ \donefalse
+\else\ifcase\pdfoutput
+ \donefalse
+\else\ifx\pdfsavepos\undefined
+ \donefalse
+\else
+ \donetrue
+\fi\fi\fi
+
+\chardef \editsyncstate \zerocount
+\chardef \editsynctracemode \zerocount
+\newcount \editsynccounter
+\newwrite \editsyncwrite
+
+\def\enableeditsync {\chardef\editsyncstate\plusone}
+\def\disableeditsync{\chardef\editsyncstate\zerocount}
+
+% The following definitions can go into the special drivers, but
+% for the moment we do it this way.
+
+\ifdone
+
+ \def\dostarteditsync
+ {\immediate\openout\editsyncwrite\jobname.pdfsync
+ \immediate\write\editsyncwrite{\jobname}%
+ \immediate\write\editsyncwrite{version 0}}
+
+ \def\dostopeditsync
+ {\closeout\editsyncwrite}
+
+ \def\doeditsyncregisterpage#1{\immediate\write\editsyncwrite{s\space\number#1}}
+ \def\doeditsyncopenfile #1{\immediate\write\editsyncwrite{(\space#1}}
+ \def\doeditsyncclosefile #1{\immediate\write\editsyncwrite{)}}
+
+ \def\doregistereditsyncnode#1#2#3% tag counter linenumber
+ {\pdfsavepos
+ \immediate\write\editsyncwrite{l\space\number#2\space\number#3}%
+ \expanded{\write\editsyncwrite{p\ifnum#1=\plusone*\fi\space\number#2\space\noexpand\the\pdflastxpos\space\noexpand\the\pdflastypos}}}
+
+\else
+
+ \let\dostarteditsync \relax
+ \let\dostopeditsync \relax
+
+ \let\doeditsyncregisterpage\gobbleoneargument
+ \let\doeditsyncopenfile \gobbleoneargument
+ \let\doeditsyncclosefile \gobbleoneargument
+ \let\doregistereditsyncnode\gobblethreearguments
+
+ % These specials could be filtered by a dvitopdf backend and
+ % written to a jobname.pdfsync file. In that case, the x and
+ % y coordinates have to be to be resolved by driver.
+
+ % \def\doeditsyncregisterpage#1{\special{pdfsync: s\space\number#1}}
+ % \def\doeditsyncopenfile #1{\special{pdfsync: ( #1}}
+ % \def\doeditsyncclosefile #1{\special{pdfsync: )}}
+
+ % \def\doregistereditsyncnode#1#2#3%
+ % {\special{pdfsync: l the\editsynccounter\space\number#3}%
+ % \special{pdfsync: p\ifnum#1=\plusone*\fi\space\number#2}}
+
+\fi
+
+\let\editsynctracer\gobbleoneargument
+
+\editsynccounter\minusone % counting starts at zero and we increment beforehand
+
+\def\registereditsyncnode#1% we assume #1 is one token
+ {\ifcase\editsyncstate
+ \expandafter\gobbleoneargument
+ \else
+ \global\advance\editsynccounter\plusone
+ \doregistereditsyncnode#1\editsynccounter\inputlineno
+ \expandafter\editsynctracer
+ \fi}
+
+\def\editsync {\registereditsyncnode\plusone *}
+\def\editsyncnode{\registereditsyncnode\zerocount}
+\def\editsynctext{\registereditsyncnode\plusone }
+
+\appendtoks \dostarteditsync \to \everystarttext
+%appendtoks \dostopeditsync \to \everystoptext
+\appendtoks \doeditsyncregisterpage\realfolio \to \everyshipout
+\appendtoks \doeditsyncopenfile\readfilename \to \everybeforereadfile
+\appendtoks \doeditsyncclosefile\readfilename \to \everyafterreadfile
+
+\appendtoks \enableeditsync \to \everystarttext
+\appendtoks \disableeditsync \to \everypagebody
+
+\def\editsynctracer#1%
+ {\ifcase\editsynctracemode\else
+ \begingroup
+ \forgetall
+ \disableeditsync
+ \ifcase\editsynctracemode\or % could be done more efficient, box around ifcase
+ \setbox\scratchbox\hbox to \zeropoint{\hss\infofont#1\hss}% 1
+ \else
+ \setbox\scratchbox\hbox to \zeropoint{\hss\traceboxplacementtrue\boxcursor\hss}% 2/3/4
+ \fi
+ \smashbox\scratchbox\box\scratchbox
+ \ifcase\editsynctracemode\or\or\or
+ \setbox\scratchbox\hbox to \zeropoint{\hss\raise1.25ex\hbox{\infofont#1}\hss}% 3
+ \smashbox\scratchbox\box\scratchbox
+ \or
+ \setbox\scratchbox\hbox to \zeropoint{\hss\lower1.25ex\hbox{\infofont#1}\hss}% 4
+ \smashbox\scratchbox\box\scratchbox
+ \fi
+ \endgroup
+ \fi}
+
+% \def\editsynctracer#1% more efficient but unreadable
+% {\ifcase\editsynctracemode\else
+% \ifcase\editsyncstate\else
+% \begingroup
+% \forgetall
+% \disableeditsync
+% \setbox\scratchbox\hbox to \zeropoint
+% {\hss
+% \ifcase\editsynctracemode\or
+% \infofont#1% 1
+% \else
+% \traceboxplacementtrue\boxcursor% 2/3/4
+% \fi
+% \hss}%
+% \smashbox\scratchbox\box\scratchbox
+% \setbox\scratchbox\hbox to \zeropoint
+% {\hss
+% \ifcase\editsynctracemode\or\or\or
+% \raise1.25ex\hbox{\infofont#1}% 3
+% \or
+% \lower1.25ex\hbox{\infofont#1}% 4
+% \fi
+% \hss}%
+% \smashbox\scratchbox\box\scratchbox
+% \endgroup
+% \fi
+% \fi}
+
+% beware, adding nodes this way will interfere with the typesetting
+
+\appendtoks \editsyncnode p\to \everypar
+\appendtoks \editsyncnode m\to \everymath
+\appendtoks \editsyncnode d\to \everydisplay
+\appendtoks \editsyncnode h\to \everyhbox
+
+% For compatibility with 'pdfsync4context' we provide:
+
+\let\pdfsyncstart\enableeditsync
+\let\pdfsyncstop \disablepdfsync
+\let\pdfsync \editsync
+
+\protect
+
+\doifnotmode{demo}{\endinput}
+
+\chardef\editsynctracemode=3
+
+\starttext
+
+\chapter{Test}
+
+\processfile{tufte}
+
+\startitemize
+\item first
+\item second
+\stopitemize
+
+\processfile{tufte}
+
+\startlines
+some local \editsync sync and \editsynctext{here}a marked point
+some local \editsync sync and \editsyncnode{here}a marked point
+\stoplines
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-educat.mkii b/tex/context/modules/mkii/m-educat.mkii
new file mode 100644
index 000000000..93b1a6c5d
--- /dev/null
+++ b/tex/context/modules/mkii/m-educat.mkii
@@ -0,0 +1,217 @@
+%D \module
+%D [ file=m-educat,
+%D version=2003.03.05,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Educational Extras,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module will collect a few macros cq.\ definitions
+%D meant for educational use. Most of the code has been laying
+%D around for some time and has been (or is still) used in
+%D \PRAGMA\ projects.
+
+\unprotect
+
+\definesystemvariable{iv}
+
+\definecolor [answerareacolor] [s=.90]
+\definecolor [answerlinecolor] [white]
+
+\definetextbackground
+ [\v!answerarea]
+ [\c!location=\v!text,
+ \c!n=0,
+ \c!frame=\v!off,
+ \c!framecolor=answerlinecolor,
+ \c!rulethickness=2pt,
+ \c!background=\v!color,
+ \c!backgroundcolor=answerareacolor,
+ \c!alternative=2] % betweenline
+
+% n=gedwongen
+% m=extra auto
+
+\def\setupanswerarea
+ {\setuptextbackground[\v!answerarea]}
+
+\setvalue\e!answerspace
+ {\dosingleempty\doanswerspace}
+
+\def\doanswerspace[#1]%
+ {\begingroup
+ \dontcomplain
+ \setupanswerarea
+ [\c!n=0,\c!m=,#1,\c!location=\v!text]%
+ \doifelsenothing{\textbackgroundparameter\c!m}
+ {\expandafter\donoanswerspace}
+ {\expandafter\dodoanswerspace}%
+ [#1]}
+
+\def\donoanswerspace[#1]#2%
+ {\setupthinrules
+ [\c!alternative=\textbackgroundparameter\c!alternative,
+ \c!color=\textbackgroundparameter\c!framecolor,
+ \c!background=\textbackgroundparameter\c!background,
+ \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor,
+ \c!rulethickness=\textbackgroundparameter\c!rulethickness]%
+ \doifelse{\textbackgroundparameter\c!n}{*}
+ {\thinrule
+ \par}
+ {\scratchcounter0\textbackgroundparameter\c!n\relax
+ % tricky, guess
+ \def\processisolatedword##1%
+ {\setbox\scratchbox=\hbox{##1}%
+ \vbox{\hsize\wd\scratchbox\thinrule
+ \ifcase\scratchcounter\else
+ \setbox\scratchbox=\hbox{\space}%
+ \nobreak\hskip\zeropoint \!!minus \wd\scratchbox
+ \vbox{\hsize\wd\scratchbox\thinrule}%
+ \fi}}%
+ \processisolatedwords{#2}\processisolatedword
+ % so far
+ \ifcase\scratchcounter \else \ifnum\scratchcounter<3
+ \nobreak \vbox{\hsize\scratchcounter em\thinrule}%
+ \else % more
+ \advance \scratchcounter -2
+ \dorecurse\scratchcounter{\allowbreak\vbox{\hsize1em\thinrule}}%
+ \nobreak \vbox{\hsize2em\thinrule}%
+ \fi \fi}%
+ \endgroup}
+
+\def\dodoanswerspace[#1]#2% m case
+ {\getvalue{\e!start\v!answerarea}%
+ #2%
+ \doifelse{\textbackgroundparameter\c!m}{*}
+ {\hfill\strut
+ \getvalue{\e!stop\v!answerarea}%
+ \par}
+ {\scratchcounter0\textbackgroundparameter\c!m\relax
+ \ifcase\scratchcounter \else \ifnum\scratchcounter<3
+ \nobreak \hbox to \scratchcounter em{\strut\hss}%
+ \else % more
+ \advance \scratchcounter -2
+ \dorecurse\scratchcounter{\allowbreak\hbox to 1em{\strut\hss}}%
+ \nobreak \hbox to 2em{\strut\hss}%
+ \fi \fi
+ \getvalue{\e!stop\v!answerarea}}%
+ \endgroup}
+
+\setvalue{\e!start\e!answerlines}%
+ {\dosingleempty\dostartanswerlines}
+
+\def\dostartanswerlines[#1]%
+ {\begingroup
+ \dontcomplain
+ \setupanswerarea
+ [\c!n=0,\c!m=,#1,\c!location=\v!text]%
+ \doifnot{\textbackgroundparameter\c!option}\v!joinedup\softbreak
+ \doifelsenothing{\textbackgroundparameter\c!m}
+ {\expandafter\donostartanswerlines}
+ {\expandafter\dodostartanswerlines}%
+ [#1]}
+
+\def\donostartanswerlines[#1]%
+ {\setupthinrules
+ [\c!alternative=\textbackgroundparameter\c!alternative,
+ \c!color=\textbackgroundparameter\c!framecolor,
+ \c!background=\textbackgroundparameter\c!background,
+ \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor,
+ \c!rulethickness=\textbackgroundparameter\c!rulethickness]%
+ \thinrules[\c!n=\textbackgroundparameter\c!n]\par
+ \endgroup
+ \grabuntil{\e!stop\e!answerlines}}
+
+\def\dodostartanswerlines[#1]%
+ {\begingroup
+ \getvalue{\e!start\v!answerarea}%
+ \ignorespaces}
+
+\setvalue{\e!stop\e!answerlines}%
+ {\scratchcounter0\textbackgroundparameter\c!m\relax
+ % a \softbreak is more efficient in pos dan \par
+ \ifcase\scratchcounter
+ % nothing
+ \or
+ \softbreak
+ \else
+ \softbreak
+ \advance \scratchcounter \minusone
+ \dorecurse\scratchcounter{\strut\hfill\strut\softbreak}%
+ \fi
+ \strut\hfill\strut
+ \getvalue{\e!stop\v!answerarea}%
+ \par\endgroup\endgroup}
+
+\setvalue\e!answerlines
+ {\dosingleempty\doanswerlines}
+
+\def\doanswerlines[#1]#2%
+ {\getvalue{\e!start\e!answerlines}[#1]%
+ #2%
+ \getvalue{\e!stop\e!answerlines}}
+
+\protect \doifnotmode{demo}{\endinput}
+
+%D Test materiaal.
+
+\starttext
+
+\startnotmode[answers]
+
+ \setupanswerarea[level=+1]
+
+\stopnotmode
+
+\setupcolors[state=start]
+
+test test test \answerspace [n=10] {Whow}. test test test
+test tets test test \answerspace [n=10] {Whow}. test test
+test test tets test test \answerspace [n=10] {Whow}. test
+test test test tets test test \answerspace [n=10] {Whow}.
+test test test test test test \answerspace [n=*] {Whow.}
+
+test test test test test test test \startanswerlines
+[n=3] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=0] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=1] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=2] What A Junk Answer \stopanswerlines
+
+\startitemize[paragraph]
+\item \startanswerlines [option=seried,n=2] xxx \stopanswerlines
+\stopitemize
+
+test test test \answerspace [m=10] {Whow}. test test test
+test tets test test \answerspace [m=10] {Whow}. test test
+test test tets test test \answerspace [m=10] {Whow}. test
+test test test tets test test \answerspace [m=10] {Whow}.
+test test test test test test \answerspace [m=*] {Whow.}
+
+test test test test test test test \startanswerlines
+[m=2] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=0] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=1] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=2] What A Junk Answer \stopanswerlines
+
+\startitemize[paragraph]
+\item \startanswerlines [option=seried,m=2] xxx \stopanswerlines
+\stopitemize
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-format.mkii b/tex/context/modules/mkii/m-format.mkii
new file mode 100644
index 000000000..7cedd803f
--- /dev/null
+++ b/tex/context/modules/mkii/m-format.mkii
@@ -0,0 +1,411 @@
+%D \module
+%D [ file=m-formay,
+%D version=ancient,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Ancient Formatting Code,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Here is some code that I had laying around and had forgotten
+%D about. Let's make it a module and see if there is interest in
+%D such things.
+
+% \defineformatblock [poem]
+% \defineformatsegment [verse] % [poem]
+% \defineformatline [line] % [verse]
+%
+% \startpoem [title] [author]
+% \startverse [ref]
+% \startline [ref]
+%
+% block : voor na tussen *tekstletter *tekstkleur
+%
+% segment : voor na tussen *tekstletter *tekstkleur
+% : links rechts linkeroffset rechteroffset
+% : ?marge *evenmarge *onevenmarge breedte
+% : nummer *nummercommando *conversie
+% : nummerletter nummerkleur *label
+%
+% line : voor na tussen *tekstletter *tekstkleur
+% : nummer *nummercommando *conversie
+% : nummerletter nummerkleur *label
+%
+% * = todo
+
+\unprotect
+
+\definesystemvariable {fx} % format block
+\definesystemvariable {fy} % format segment
+\definesystemvariable {fz} % format line
+
+\def\defineformatblock
+ {\dodoubleempty\dodefineformatblock}
+
+\def\dodefineformatblock[#1][#2]%
+ {\setupformatblock
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,#2]%
+ \setvalue{\e!start#1}{\startformatblock[#1]}%
+ \setvalue{\e!stop #1}{\stopformatblock}}
+
+\def\setupformatblock
+ {\dodoubleempty\dosetupformatblock}
+
+\def\setupformatblock[#1]%
+ {\getparameters[\??fx#1]}
+
+\def\startformatblock[#1]%
+ {\dotriplegroupempty\dostartformatblock{#1}}
+
+\def\dostartformatblock#1#2#3
+ {\bgroup
+ \getvalue{\??fx#1\c!before}
+ \doglobal\newcounter\formatsegmentcounter
+ \doglobal\newcounter\formatlinecounter
+ \doglobal\newcounter\formatlinesubcounter
+ \doglobal\newcounter\formatlinemaxcounter
+ \doifsomething{#2}{\leftaligned{#2}\getvalue{\??fx#1\c!inbetween}}
+ \def\stopformatblock%
+ {\doifsomething{#3}{\getvalue{\??fx#1\c!inbetween}\leftaligned{#3}}
+ \getvalue{\??fx#1\c!after}
+ \egroup}}
+
+\def\defineformatsegment
+ {\dodoubleempty\dodefineformatsegment}
+
+\def\dodefineformatsegment[#1][#2]%
+ {\setupformatsegment
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,\c!left=,\c!right=,
+ \c!leftoffset=\!!zeropoint,\c!rightoffset=\!!zeropoint,
+ %\c!margin=\!!zeropoint,\c!evenmargin=\!!zeropoint,\c!oddmargin=\hsize,
+ \c!width=\hsize,\c!numberstyle=,\c!numbercolor=,\c!number=\v!no,
+ \c!numbercommand=,\c!conversion=,\c!label=,
+ #2]%
+ \setvalue{\e!start#1}{\startformatsegment[#1]}%
+ \setvalue{\e!stop #1}{\stopformatsegment}}
+
+\def\setupformatsegment
+ {\dodoubleempty\dosetupformatsegment}
+
+\def\setupformatsegment[#1]%
+ {\getparameters[\??fy#1]}
+
+\def\placeformatsegmentcounter
+ {\formatsegmentcounter\quad\hphantom{\placeformatlinecounter}}
+
+\def\placeformatlinecounter
+ {\formatlinecounter}
+
+\def\startformatsegment[#1]%
+ {\bgroup
+ \doifelsevalue{\??fy#1\c!number}\v!yes
+ {\def\doplaceformatsegmentcounter
+ {\inleftmargin
+ {\doattributes{\??fy#1}\c!numberstyle\c!numbercolor
+ {\placeformatsegmentcounter}}}}
+ {\let\doplaceformatsegmentcounter\relax}%
+ \getvalue{\??fy#1\c!before}
+ \doglobal\increment\formatsegmentcounter
+ \def\formatrightoffset{\getvalue{\??fy#1\c!rightoffset}}
+ \def\formatleftoffset {\getvalue{\??fy#1\c!leftoffset}}
+ \def\formatminwidth {\getvalue{\??fy#1\c!minwidth}}
+ \def\formatwidth {\getvalue{\??fy#1\c!width}}
+ %\def\formatmargin {\getvalue{\??fy#1\c!margin}}
+ \def\formatbefore {\getvalue{\??fy#1\c!before}}
+ \def\formatinbetween {\getvalue{\??fy#1\c!inbetween}}
+ \def\formatafter {\getvalue{\??fy#1\c!after}}
+ \def\formatleft {\getvalue{\??fy#1\c!left}}
+ \def\formatright {\getvalue{\??fy#1\c!right}}
+ \@@segmentvarianta
+ \getvalue{@@segmentvariant\getvalue{\??fy#1\c!alternative}}
+ \def\stopformatsegment
+ {\getvalue{\??fy#1\c!after}
+ \egroup}}
+
+\newif\iftraceformatblock
+
+\def\@@segmentvarianta % ragged right, symbols
+ {\let\formatraggedness\raggedright
+ \let\dostartformatline\dostartformatlineab
+ \let\formatleftfirst\relax \let\formatrightfirst\hfill
+ \let\formatleftnext \hfill \let\formatrightnext \relax}
+
+\def\@@segmentvariantb % ragged right, equal parts, symbols
+ {\let\formatraggedness\raggedcenter
+ \let\dostartformatline\dostartformatlineab
+ \let\formatleftfirst\relax \let\formatrightfirst\hfill
+ \let\formatleftnext \hfill \let\formatrightnext \relax}
+
+\def\@@segmentvariantc % ragged right
+ {\let\formatraggedness\veryraggedright
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\relax \let\formatrightnext\hfill}
+
+\def\@@segmentvariantd % ragged center
+ {\let\formatraggedness\veryraggedcenter
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\hfill \let\formatrightnext\hfill}
+
+\def\@@segmentvariante % ragged left
+ {\let\formatraggedness\veryraggedleft
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\hfill \let\formatrightnext\relax}
+
+\def\defineformatline
+ {\dodoubleempty\dodefineformatline}
+
+\def\dodefineformatline[#1][#2]%
+ {\setupformatline
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,
+ \c!number=\v!no,\c!numbercommand=,\c!conversion=,
+ \c!numberstyle=,\c!numbercolor=,\c!label=,
+ #2]%
+ \setvalue{\e!start#1}{\startformatline[#1]}%
+ \setvalue{\e!stop #1}{\stopformatline}}
+
+\def\setupformatline
+ {\dodoubleempty\dosetupformatline}
+
+\def\setupformatline[#1]%
+ {\getparameters[\??fz#1]}
+
+\newconditional\formatforcedbreak
+
+\def\startformatline[#1]%
+ {\bgroup
+ \doifelsevalue{\??fz#1\c!number}\v!yes
+ {\def\doplaceformatlinecounter
+ {\inleftmargin
+ {\doattributes{\??fz#1}\c!numberstyle\c!numbercolor
+ {\placeformatlinecounter}}}}
+ {\let\doplaceformatlinecounter\relax}%
+ \global\setfalse\formatforcedbreak
+ \def\\{\break\global\settrue\formatforcedbreak}%
+ \hsize\formatwidth
+ \doglobal\increment\formatlinecounter
+ \par
+ \nobreak
+ \def\stopformatline
+ {\unskip\unskip\unskip\unskip\unskip\egroup
+ \let\doplaceformatsegmentcounter\relax}
+ \postponenotes
+ \dowithnextbox{\dostartformatline}\hbox\bgroup\ignorespaces}
+
+\def\dostartformatlineab
+ {%\dosetleftskipadaption\formatmargin
+ %\advance\hsize-\leftskipadaption\relax
+ \ifdim\nextboxwd>\hsize
+ \beginofshapebox
+ \forgetall
+ \hangafter\plusone
+ \hangindent\formatleftoffset
+ \formatraggedness
+ \hskip\formatrightoffset
+ \unhbox\nextbox\par
+ \endofshapebox
+ %\advance\hsize \leftskipadaption
+ \doglobal\newcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\increment\formatlinesubcounter}
+ \global\let\formatlinemaxcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\decrement\formatlinesubcounter
+ \ifnum\formatlinesubcounter=\zerocount
+ \doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ \hskip-\formatrightoffset
+ %\hskip\leftskipadaption
+ \formatleftfirst
+ \unhbox\shapebox
+ \ifnum\formatlinemaxcounter>\plusone
+ \ifx\formatright\empty\else
+ \shapedhbox to \zeropoint{\formatright\hss}%
+ \fi
+ \fi
+ \formatrightfirst
+ \iftraceformatblock
+ \ruledhskip\formatrightoffset\hskip-\formatrightoffset
+ \fi
+ \else
+ %\hskip\leftskipadaption
+ \iftraceformatblock
+ \ruledhskip\formatleftoffset\hskip-\formatleftoffset
+ \fi
+ \formatleftnext
+ \ifx\formatleft\empty\else
+ \shapedhbox to \zeropoint{\hss\formatleft}%
+ \fi
+ \unhbox\shapebox
+ \formatrightnext
+ \fi}
+ \flushshapebox
+ \else
+ \dontleavehmode\hbox
+ {\doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ %\hskip\leftskipadaption
+ \formatleftfirst
+ \unhbox\nextbox
+ \formatrightfirst}
+ \fi
+ \par
+ \egroup}
+
+\def\dostartformatlinecde
+ {%\dosetleftskipadaption\formatmargin
+ %\advance\hsize -\leftskipadaption\relax
+ \dimen0=\hsize
+ \ifconditional\formatforcedbreak\else
+ \ifdim\formatminwidth>\zeropoint\relax
+ \ifdim\nextboxwd>\hsize
+ \doloop
+ {\global\dimen1=\dimen0
+ \beginofshapebox
+ \hsize\dimen0
+ \forgetall
+ \formatraggedness
+ \unhcopy\nextbox\par
+ \endofshapebox
+ \reshapebox
+ {\setbox\scratchbox=\hbox{\unhbox\shapebox}%
+ \ifdim\wd\scratchbox<\dimen1
+ \global\dimen1=\wd\scratchbox
+ \fi}
+ \ifdim\dimen1<\formatminwidth\relax
+ \advance\dimen0 by -.25em
+ \else
+ \exitloop
+ \fi
+ \ifdim\dimen0<10em
+ \dimen0=\hsize
+ \exitloop
+ \fi}
+ \fi
+ \fi
+ \fi
+ \beginofshapebox
+ \hsize\dimen0
+ \forgetall
+ \formatraggedness
+ \unhcopy\nextbox\par
+ \endofshapebox
+ %\advance\hsize \leftskipadaption
+ \doglobal\newcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\increment\formatlinesubcounter}%
+ \global\let\formatlinemaxcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\decrement\formatlinesubcounter
+ \ifnum\formatlinesubcounter=\zerocount
+ \doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ \fi
+ %\hskip\leftskipadaption
+ \formatleftnext
+ \unhbox\shapebox
+ \formatrightnext\strut}% strut prevents unskip
+ \flushshapebox
+ \par
+ \egroup}
+
+\defineformatblock[poem]
+ [\c!before=\blank,
+ \c!inbetween={\blank[\v!medium]},
+ \c!after=\blank]
+
+\defineformatsegment[verse]
+ [\c!alternative=\v!left,
+ \c!width=\hsize,
+ %\c!margin=\!!zeropoint,
+ \c!before={\blank[\v!medium]},
+ \c!after={\blank[\v!medium]},
+ \c!inbetween={\blank[\v!medium]},
+ \c!leftoffset=3em,
+ \c!rightoffset=2em,
+ \c!minwidth=5em,
+ \c!left={$[$\enspace},
+ \c!right={\enspace$]$}]
+
+\defineformatline[line]
+ []
+
+\protect
+
+\doifnotmode{demo} {\endinput}
+
+% evt defineblank[formatbefore,formatinbetween,formatafter]
+
+%\showframe \traceformatblocktrue
+
+\usemodule[visual]
+
+\setuplayout[height=middle,topspace=1cm,header=0pt,footer=0pt]
+\setupbodyfont[10pt]
+
+% All interfaces supported, but testing with english; todo:
+% more options, more alternatives, inheritance and mixed
+% definitions, and so.
+
+\starttext
+
+\startbuffer
+\startbuffer[poem]
+\startpoem{A Random Poem}{Hans Hagen}
+ \startverse
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \stopverse
+ \startverse
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \stopverse
+\stoppoem
+\stopbuffer
+
+\setupformatsegment[verse][width=.4\hsize,number=yes,numberstyle=slanted]
+\setupformatline [line] [number=yes,numberstyle=smallslanted]
+
+\startbuffer[x]
+\setupformatsegment[verse][leftoffset=0pt,rightoffset=0pt,left=,right=]
+\stopbuffer
+
+\section{Alternative A}
+
+\setupformatsegment[verse][alternative=a] {\getbuffer[poem]}
+\setupformatsegment[verse][alternative=a] {\getbuffer[x,poem]}
+
+\section{Alternative B}
+
+\setupformatsegment[verse][alternative=b] {\getbuffer[poem]}
+\setupformatsegment[verse][alternative=b] {\getbuffer[x,poem]}
+
+\section{Alternative C}
+
+\setupformatsegment[verse][alternative=c] {\getbuffer[poem]}
+
+\section{Alternative D}
+
+\setupformatsegment[verse][alternative=d] {\getbuffer[poem]}
+
+\section{Alternative E}
+
+\setupformatsegment[verse][alternative=e] {\getbuffer[poem]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-graph.mkii b/tex/context/modules/mkii/m-graph.mkii
new file mode 100644
index 000000000..8e28cf537
--- /dev/null
+++ b/tex/context/modules/mkii/m-graph.mkii
@@ -0,0 +1,231 @@
+%D \module
+%D [ file=m-graph,
+%D version=2000.08.06,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\METAPOST\ graph module support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D I finally finished graph support, if only because I could
+%D not stand the idea that Karel Wesseling would revert to
+%D \PiCTeX.
+
+% pre 2000.08.06 version
+%
+% \forceMPTEXgraphictrue
+%
+% \startMPinitializations
+% initialize_numbers ; % make sure that pseudo typesetting is set up
+% input graph ; % load the graph package
+% Autoform := "@g" ; % change the % template char into @
+% \stopMPinitializations
+
+%D The latest version does things more automatically (and
+%D efficiently when no text processing is needed). For
+%D definitions embedded in your document, you need to
+%D use \type {@} as template character, in external files,
+%D \type {%} is also supported.
+
+\startMPinclusions
+ input graph ;
+\stopMPinclusions
+
+%D Graphics that have \type {begingraph} in them are
+%D recognized as such and force handling of embedded \TEX\
+%D code.
+
+\forceMPTEXcheck{begingraph}
+
+%D If you run into troubles, try:
+%D
+%D \starttyping
+%D \forceMPTEXgraphictrue
+%D \stoptyping
+%D
+%D A demo can be run with:
+%D
+%D \starttyping
+%D texexec --mode=demo --pdf m-graph
+%D \stoptyping
+
+\startMPinclusions
+ % @# is X_ or Y_; $ is Gxcvlin_ or Gycvlin_; l and h are numeric or string
+ % It would not be OK to set (@#low,@#high) to a pair expression because $ might
+ % try to rescale @#low when evaluating the right-hand side for @#high.
+ vardef Gsetr_@\#(suffix $)(expr l, h) =
+ Gclbnds_@\# ;
+ if @\#ctyp>0 :
+ @\#low = if abs @\#ctyp<>log: $ fi Mlog_Str l ;
+ @\#high = if abs @\#ctyp<>log: $ fi Mlog_Str h ;
+ else :
+ -@\#high = if abs @\#ctyp<>log: $ fi Mlog_Str l ;
+ -@\#low = if abs @\#ctyp<>log: $ fi Mlog_Str h ;
+ fi
+ enddef ;
+\stopMPinclusions
+
+\doifnotmode {demo} {\endinput}
+
+%D You need to have the data files in your path,
+%D otherwise the run is aborted.
+
+\doiffileelse {agepop91.d} {} {\writestatus{graph}{no data files found}\wait\end}
+
+%D The test:
+
+\starttext
+
+\startMPpage
+draw begingraph(3in,2in);
+ gdraw "agepop91.d";
+ endgraph;
+\stopMPpage
+
+\startMPpage
+draw begingraph(3in,2in);
+ gdraw "agepop91.d" plot btex$\bullet$etex;
+ endgraph;
+\stopMPpage
+
+\startMPpage
+draw begingraph(3in,2in);
+ glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT);
+ glabel.bot(btex Age in years etex, OUT);
+ gdraw "agepopm.d";
+ endgraph;
+\stopMPpage
+
+\startMPpage
+draw begingraph(3in,2in);
+ glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT);
+ glabel.bot(btex Age in years etex, OUT);
+ setrange(origin, whatever,whatever);
+ gdraw "agepopm.d";
+ endgraph;
+\stopMPpage
+
+\startMPpage
+draw begingraph(2.3in,2in);
+ setcoords(log,log);
+ glabel.lft(btex Seconds etex,OUT);
+ glabel.bot(btex Matrix size etex,
+ OUT);
+ gdraw "matmul.d" dashed evenly;
+ glabel.ulft(btex Standard etex,8);
+ gdraw "matmul.d";
+ glabel.lrt(btex Strassen etex,7);
+ endgraph;
+\stopMPpage
+
+\startMPpage
+draw begingraph(6.5cm,4.5cm);
+ setrange(80,0, 90,whatever);
+ glabel.bot(btex Year etex, OUT);
+ glabel.lft(btex \vbox{\hbox{Emissions in} \hbox{thousands of}
+ \hbox{metric tons} \hbox{(heavy line)}}etex, OUT);
+ gdraw "lead.d" withpen pencircle scaled 1.5pt;
+ autogrid(,otick.lft);
+ setcoords(linear,linear);
+ setrange(80,0, 90,whatever);
+ glabel.rt(btex \vbox{\hbox{Micrograms} \hbox{per cubic}
+ \hbox{meter of air} \hbox{(thin line)}}etex, OUT);
+ gdraw "lead.d";
+ autogrid(otick.bot,otick.rt);
+ endgraph;
+\stopMPpage
+
+\stoptext
+
+% No longer needed, since John will fix it.
+%
+% %D For the moment we need the following patch. Adam T. Lindsay
+% %D found out that the following code produced an error:
+% %D
+% %D \starttyping
+% %D \startMPcode
+% %D draw begingraph(130mm,35mm);
+% %D setrange(0,0,10,22000);
+% %D glabel.lft(btex {correct 0--22000} etex rotated 90, OUT);
+% %D autogrid(itick.bot,grid.lft) withcolor .75white ;
+% %D endgraph;
+% %D \stopMPcode
+% %D
+% %D \startMPcode
+% %D draw begingraph(130mm,35mm);
+% %D setrange(0,50,10,22000);
+% %D glabel.lft(btex {wrong 50--22000} etex rotated 90, OUT);
+% %D autogrid(itick.bot,grid.lft) withcolor .75white ;
+% %D endgraph;
+% %D \stopMPcode
+% %D
+% %D \startMPcode
+% %D draw begingraph(130mm,35mm);
+% %D setrange(0,110,10,30000);
+% %D glabel.lft(btex {failed 110--22000} etex rotated 90, OUT);
+% %D autogrid(itick.bot,grid.lft) withcolor .75white ;
+% %D endgraph;
+% %D \stopMPcode
+% %D \stoptyping
+% %D
+% %D The bug is a rather nasty one and needs some tweaking in
+% %D the low level graph code. John Hobby suggested for the
+% %D moment to initialize \type {setrange} as follows:
+% %D
+% %D \starttyping
+% %D setrange(0,0,"22000","22000")
+% %D \stoptyping
+% %D
+% %D Folowing this suggesion, I provide the following
+% %D extension:
+
+% def begingraph(expr w, h) =
+% begingroup
+% save X_, Y_, Gfin_, Gcur_, Gcbb_, Gneedgr_, Gneedfr_, Gdidsc_;
+% save Gdpic_, Gppic_, Ggl_, Garw_;
+% picture Gfin_, Gcur_, Gcbb_, Gdpic_, Gppic_, Ggl_[];
+% boolean Gneedgr_, Gneedfr_, Gdidsc_;
+% Gfin_ = nullpicture;
+% Gcur_ = nullpicture;
+% Gcbb_ = nullpicture;
+% X_.ctyp = Y_.ctyp = linear;
+% Z_.gdim = (w,h);
+% X_.sc = Y_.sc = 0;
+% Gneedgr_ = true;
+% Gneedfr_ = true;
+% Gdidsc_ = false;
+% Gdpic_ = nullpicture;
+% Garw_ = 0;
+% scantokens everybegingraph ;
+% enddef;
+%
+% boolean fixsetrange ; fixsetrange := true ;
+%
+% vardef dosetrange(text t) =
+% interim warningcheck:=0;
+% save r_; r_=0;
+% string r_[]s;
+% for x_=
+% for p_=t: if pair p_: xpart p_, ypart fi p_, endfor:
+% r_[incr r_] if string x_: s fi = x_;
+% if r_>2:
+% Gsetr_ if r_=3: X_(Gxcvlin_) else: Y_(Gycvlin_) fi(
+% r_[r_-2] if unknown r_[r_-2]: s fi, x_);
+% fi
+% exitif r_=4;
+% endfor
+% enddef;
+%
+% vardef setrange(text t) =
+% if fixsetrange : dosetrange(0,0,20000,20000) ; fi ;
+% dosetrange(t) ;
+% enddef ;
+%
+% if unknown everybegingraph :
+% string everybegingraph ;
+% % everybegingraph := "setrange(0,0,20000,20000)" ;
+% fi ;
diff --git a/tex/context/modules/mkii/m-layout.mkii b/tex/context/modules/mkii/m-layout.mkii
new file mode 100644
index 000000000..5ccf0e987
--- /dev/null
+++ b/tex/context/modules/mkii/m-layout.mkii
@@ -0,0 +1,102 @@
+%D \module
+%D [ file=m-layout,
+%D version=2004.01.16,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Additional Layouts,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% layout-preset - thf th tf
+
+%D This is a preliminary module, don't depend on these dimensions yet.
+
+\readsysfile{lang-frq}\donothing\donothing
+\readsysfile{lang-frd}\donothing\donothing
+
+\unprotect
+
+% \def\layouthwratio{\withoutpt\the\dimexpr8\paperheight/\dimexpr(\paperwidth/ 8192)\relax}
+% \def\layouthwratio{\withoutpt\the\dimexpr4\paperheight/\dimexpr(\paperwidth/16384)\relax}
+% \def\layouthwratio{\withoutpt\the\dimexpr2\paperheight/\dimexpr(\paperwidth/32768)\relax}
+
+\def\layouthwratio
+ {\withoutpt\the\dimexpr2\paperheight/(\paperwidth/32768)\relax}
+
+\def\layouthfheight
+ {\dimexpr\layoutparameter\c!header+\layoutparameter\c!headerdistance+
+ \layoutparameter\c!footer+\layoutparameter\c!footerdistance\relax}
+
+\startsetups[preset-1]
+
+ \xdef\layoutwidth {\dimexpr\layoutparameter\c!width\relax}
+ \gdef\layoutheight{\dimexpr\layouthwratio\dimexpr\layoutwidth\relax+\layouthfheight\relax}
+
+\stopsetups
+
+\definelayout
+ [preset-1-1]
+ [\c!preset=preset-1,
+ \c!backspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax,
+ \c!width=\dimexpr2\paperwidth/3\relax,
+ \c!cutspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax,
+ \c!margin=\dimexpr(\paperwidth-\layoutwidth)/3\relax,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance, % \lineheight,
+ \c!footer=\layoutparameter\c!header, % 2\lineheight,
+ \c!topspace=\dimexpr1\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax,
+ \c!bottomspace=\dimexpr2\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax]
+
+\startsetups[preset-2]
+
+ \gdef\layouthstep{\dimexpr\paperwidth /\layoutparameter\c!columns\relax}
+ \gdef\layoutvstep{\dimexpr\paperheight/\layoutparameter\c!columns\relax}
+
+\stopsetups
+
+\definelayout
+ [preset-2-1]
+ [\c!preset=preset-2,
+ \c!columns=12,
+ \c!backspace=\layouthstep,
+ \c!width=\v!middle,
+ \c!cutspace=2\layouthstep,
+ \c!margin=\layouthstep,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance,
+ \c!footer=\layoutparameter\c!header,
+ \c!topspace=\dimexpr\layoutvstep-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax,
+ \c!bottomspace=\dimexpr(2\layoutvstep)-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax]
+
+\definelayout
+ [preset-2-2]
+ [\c!preset=preset-2,
+ \c!columns=12,
+ \c!backspace=\layouthstep,
+ \c!width=\v!middle,
+ \c!cutspace=2\layouthstep,
+ \c!margin=\layouthstep,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance,
+ \c!footer=\layoutparameter\c!header,
+ \c!topspace=\layoutvstep,
+ \c!bottomspace=\layoutvstep] % maybe 1.5
+
+% \setuplayout[preset-1-1] test \showframe \page
+% \setuplayout[preset-1-1][width=65\averagecharwidth] \setuplayout[preset-1-1] test \showframe \page
+% \setuplayout[preset-2-1] test \showframe \page
+% \setuplayout[preset-2-1][columns=10] \setuplayout[preset-2-1] test \showframe \page
+% \setuplayout[preset-2-2] test \showframe \page
+% \setuplayout[preset-2-2][columns=10] \setuplayout[preset-2-2] test \showframe \page
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-level.mkii b/tex/context/modules/mkii/m-level.mkii
new file mode 100644
index 000000000..d758288d7
--- /dev/null
+++ b/tex/context/modules/mkii/m-level.mkii
@@ -0,0 +1,94 @@
+%D \module
+%D [ file=level,
+%D version=2002.10.20,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Catching Nesting Errors,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\newcount\currentnesting
+
+\def\startnesting#1%
+ {\global\advance\currentnesting\plusone
+ \setxvalue{level::\number\currentnesting}{#1}}
+
+\def\stopnesting#1%
+ {\edef\nestingstring{#1}%
+ \relax\ifnum\currentnesting>\zerocount
+ \doifelsevalue{level::\number\currentnesting}\nestingstring
+ {\global\advance\currentnesting\minusone}
+ {\@EA\reportnestingerror\@EA\stoptext}
+ \else
+ \@EA\reportnestingerror\@EA\stoptext
+ \fi}
+
+\def\checknesting
+ {\relax\ifnum\currentnesting>\zerocount
+ \def\nestingstring{end of document}%
+ \@EA\reportnestingerror
+ \fi}
+
+\def\reportnestingerror
+ {\endgraf
+ \global\let\checknesting\relax
+ \bgroup \definedfont[Mono at 18pt]\incolortrue
+ \setupinterlinespace
+ \raggedright
+ \bgroup \red
+ \ifnum\currentnesting>\plusone
+ wrong end level
+ \else
+ too many end levels
+ \fi
+ at \nestingstring\space in line \number\inputlineno
+ \ifnum\currentnesting>\zerocount, stack:\fi\endgraf
+ \egroup
+ \dostepwiserecurse\currentnesting\plusone\minusone
+ {\space\getvalue{level::\recurselevel}}
+ \endgraf
+ \egroup
+ \writestatus\m!systems{quitting due to level error}\wait
+ \batchmode}
+
+\prependtoks
+ \checknesting
+\to \everystoptext
+
+\protect \doifnotmode{demo}{\endinput}
+
+\starttext
+
+% \startnesting{eerste}
+% \startnesting{tweede}
+% \startnesting{derde}
+% \startnesting{vierde}
+% test
+% \stopnesting{vierde}
+% \stopnesting{eerste}
+
+% \startnesting{eerste}
+% \startnesting{tweede}
+% test
+% \stopnesting{vierde}
+% \stopnesting{derde}
+% \stopnesting{tweede}
+% \stopnesting{eerste}
+
+\startnesting{eerste}
+ \startnesting{tweede}
+ \startnesting{derde}
+ \startnesting{vierde}
+ test
+ \stopnesting{vierde}
+ \stopnesting{derde}
+ \stopnesting{tweede}
+\stopnesting{eerste}
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-narrowtt.mkii b/tex/context/modules/mkii/m-narrowtt.mkii
new file mode 100644
index 000000000..129bf270b
--- /dev/null
+++ b/tex/context/modules/mkii/m-narrowtt.mkii
@@ -0,0 +1,39 @@
+%D \module
+%D [ file=m-narrowtt,
+%D version=2005.09.08,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Narrow Verbatim,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Test file
+%D
+%D \starttyping
+%D \startTEX
+%D \usemodule[narrowtt]
+%D \starttext
+%D \starttyping
+%D Test test test.
+%D \stoptyping
+%D test \type {test} test \type{test} test
+%D \starttyping
+%D Test test test.
+%D \stoptyping
+%D \stoptext
+%D \stopTEX
+
+\unprotect
+
+\definetypeface
+ [narrowtt] [tt]
+ [mono] [modern-condensed] [default] [encoding=\defaultencoding]
+
+\definetyping[n\v!typing] \setuptyping[n\v!typing][style=\narrowtt]
+\definetype [n\v!type] \setuptype [n\v!type] [style=\narrowtt]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-obsolete.mkii b/tex/context/modules/mkii/m-obsolete.mkii
new file mode 100644
index 000000000..a97002cf6
--- /dev/null
+++ b/tex/context/modules/mkii/m-obsolete.mkii
@@ -0,0 +1,5 @@
+\unprotect
+
+\writestatus\m!systems{skipping obsolete module}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-pdfsnc.mkii b/tex/context/modules/mkii/m-pdfsnc.mkii
new file mode 100644
index 000000000..12e2e2d68
--- /dev/null
+++ b/tex/context/modules/mkii/m-pdfsnc.mkii
@@ -0,0 +1,200 @@
+%D \module
+%D [ file=m-pdfsnc,
+%D version=2003.12.23,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Editor Synchronization,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \enablemode[demo]
+
+% This file is a variation of the file pdfsync4context.tex that ships
+% with the pdfsync package (used by iTeXMac and TeXShop) by Piero
+% D'Ancona and Jrme Laurens. I made the macros a bit more efficient
+% and added some basic tracing options as well as a few more options.
+% I made this one while playing a bit with the Mac and TeX). Maybe I'll
+% add a bit of support to the kernel in in order to get rid of redundant
+% markers. Also, this had better be rewritten in a bit less \pdf
+% dependent way so that it can also be supported by dvipdfmx. I could
+% write a generic file as well, but since there is already support for
+% other packages I'll not do that (now).
+
+% compatible commands:
+%
+% \pdfsyncstart \pdfsyncstop \pdfsync
+%
+% extra commands:
+%
+% \enablepdfsync \disablepdfsync \pdfsynctext \pdfsyncnode \pdfsynctracemode
+
+\ifx\pdfoutput\undefined
+ \donefalse
+\else\ifcase\pdfoutput
+ \donefalse
+\else\ifx\pdfsavepos\undefined
+ \donefalse
+\else
+ \donetrue
+\fi\fi\fi
+
+\chardef \pdfsyncstate \zerocount
+\chardef \pdfsynctracemode \zerocount
+
+\ifdone
+
+ \writestatus{pdfsync}{loading and enabling synchronization support}
+
+\else
+
+ \writestatus{pdfsync}{synchronization is only available with pdftex}
+
+ \let \pdfsyncstart \relax % brr, not per se symmetrically used, so
+ \let \pdfsyncstop \relax % enable and disable are better names
+ \let \pdfsync \relax
+
+ \let \pdfsynctext \gobbleoneargument
+ \let \pdfsyncnode \gobbleoneargument
+
+ \let \enablepdfsync \pdfsyncstart
+ \let \disablepdfsync \pdfsyncstop
+
+ \expandafter\endinput
+\fi
+
+\unprotect % not really needed
+
+\newcount \pdfsynccounter
+\newwrite \pdfsyncwrite
+
+\def\pdfsyncstart{\chardef\pdfsyncstate\plusone} \let\enablepdfsync \pdfsyncstart
+\def\pdfsyncstop {\chardef\pdfsyncstate\zerocount} \let\disablepdfsync\pdfsyncstop
+
+\def\dostartpdfsync
+ {\immediate\openout\pdfsyncwrite\jobname.pdfsync
+ \immediate\write\pdfsyncwrite{\jobname}%
+ \immediate\write\pdfsyncwrite{version 0}}
+
+\def\dostoppdfsync
+ {\immediate\closeout\pdfsyncwrite}
+
+\def\doregisterpdfsyncpage
+ {\immediate\write\pdfsyncwrite{s\space\realfolio}}
+
+\def\dopdfsyncopenfile
+ {\immediate\write\pdfsyncwrite{(\space\readfilename}}
+
+\def\dopdfsyncclosefile
+ {\immediate\write\pdfsyncwrite{)}}
+
+\def\doregisterpdfsyncnode#1%
+ {\ifcase\pdfsyncstate\else
+ \pdfsavepos
+ \immediate\write\pdfsyncwrite{l\space\the\pdfsynccounter\space\the\inputlineno}%
+ \expanded{\write\pdfsyncwrite{p\ifnum#1=\plusone*\fi\space\the\pdfsynccounter\space\noexpand\the\pdflastxpos\space\noexpand\the\pdflastypos}}%
+ \global\advance\pdfsynccounter\plusone
+ \fi}
+
+\let\pdfsynctracer\gobbleoneargument
+
+\def\pdfsync {\doregisterpdfsyncnode\plusone \pdfsynctracer*}
+\def\pdfsyncnode{\doregisterpdfsyncnode\zerocount\pdfsynctracer}
+\def\pdfsynctext{\doregisterpdfsyncnode\plusone \pdfsynctracer}
+
+\appendtoks \dostartpdfsync \to \everystarttext
+%appendtoks \dostoppdfsync \to \everystoptext
+\appendtoks \doregisterpdfsyncpage \to \everyshipout
+\appendtoks \dopdfsyncopenfile \to \everybeforereadfile
+\appendtoks \dopdfsyncclosefile \to \everyafterreadfile
+
+\appendtoks \enablepdfsync \to \everystarttext
+\appendtoks \disablepdfsync \to \everypagebody
+
+% beware, adding nodes this way will interfere with the typesetting
+
+\appendtoks \pdfsyncnode p\to \everypar
+\appendtoks \pdfsyncnode m\to \everymath
+\appendtoks \pdfsyncnode h\to \everyhbox
+
+% just for fun
+
+\def\pdfsynctracer#1%
+ {\ifcase\pdfsynctracemode\else
+ \ifcase\pdfsyncstate\else
+ \begingroup
+ \forgetall
+ \disablepdfsync
+ \ifcase\pdfsynctracemode\or % could be done more efficient, box around ifcase
+ \setbox\scratchbox\hbox to \zeropoint{\hss\infofont#1\hss}% 1
+ \else
+ \setbox\scratchbox\hbox to \zeropoint{\hss\traceboxplacementtrue\boxcursor\hss}% 2/3/4
+ \fi
+ \smashbox\scratchbox\box\scratchbox
+ \ifcase\pdfsynctracemode\or\or\or
+ \setbox\scratchbox\hbox to \zeropoint{\hss\raise1.25ex\hbox{\infofont#1}\hss}% 3
+ \smashbox\scratchbox\box\scratchbox
+ \or
+ \setbox\scratchbox\hbox to \zeropoint{\hss\lower1.25ex\hbox{\infofont#1}\hss}% 4
+ \smashbox\scratchbox\box\scratchbox
+ \fi
+ \endgroup
+ \fi
+ \fi}
+
+% \def\pdfsynctracer#1% more efficient but unreadable
+% {\ifcase\pdfsynctracemode\else
+% \ifcase\pdfsyncstate\else
+% \begingroup
+% \forgetall
+% \disablepdfsync
+% \setbox\scratchbox\hbox to \zeropoint
+% {\hss
+% \ifcase\pdfsynctracemode\or
+% \infofont#1% 1
+% \else
+% \traceboxplacementtrue\boxcursor% 2/3/4
+% \fi
+% \hss}%
+% \smashbox\scratchbox\box\scratchbox
+% \setbox\scratchbox\hbox to \zeropoint
+% {\hss
+% \ifcase\pdfsynctracemode\or\or\or
+% \raise1.25ex\hbox{\infofont#1}% 3
+% \or
+% \lower1.25ex\hbox{\infofont#1}% 4
+% \fi
+% \hss}%
+% \smashbox\scratchbox\box\scratchbox
+% \endgroup
+% \fi
+% \fi}
+
+\protect
+
+\doifnotmode{demo}{\endinput}
+
+\chardef\pdfsynctracemode=3
+
+\starttext
+
+\chapter{Test}
+
+\processfile{tufte}
+
+\startitemize
+\item first
+\item second
+\stopitemize
+
+\processfile{tufte}
+
+\startlines
+some local \pdfsync sync and \pdfsynctext{here}a marked point
+some local \pdfsync sync and \pdfsyncnode{here}a marked point
+\stoplines
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-pictex.mkii b/tex/context/modules/mkii/m-pictex.mkii
new file mode 100644
index 000000000..e27bf6315
--- /dev/null
+++ b/tex/context/modules/mkii/m-pictex.mkii
@@ -0,0 +1,239 @@
+%D \module
+%D [ file=m-pictex,
+%D version=1997.01.15,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PICTEX\ Loading Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is one big hack. This hack is not needed when
+%D using \ETEX, so there we simply load \PICTEX\ and quit.
+
+%D Not every package defines \type{\fiverm}, \PICTEX's pixel,
+%D so let's take care of that omision here. The actual loading
+%D of \PICTEX\ depends on the package. For \LATEX\ users we
+%D take care of loading the auxiliary ones too.
+
+\def\loadpictex
+ {\ifx\grid\undefined \else \let\normalgrid\grid \fi
+ \ifx\axis\undefined \else \let\normalaxis\axis \fi
+ \ifx\undefined\fiverm
+ \font\fiverm=cmr5
+ \fi
+ \ifx\beginpicture\undefined
+ \ifx\newenvironment\undefined
+ \loadmarkfile{thrd-pic}%
+ \else
+ \input prepictex.tex \relax
+ \input pictex.tex \relax
+ \input postpictex.tex \relax
+ \fi
+ \fi
+ \ifx\normalgrid\undefined \else
+ \let\pictexgrid\grid
+ \let\grid\normalgrid
+ \fi
+ \ifx\normalaxis\undefined \else
+ \let\pictexaxis\axis
+ \let\axis\normalaxis
+ \fi}
+
+\ifx\eTeXversion\undefined \else \loadpictex \expandafter \endinput \fi
+
+%D When not in \ETEX\ and not in \CONTEXT, we load a few
+%D auxiliary macros.
+
+\ifx \undefined \writestatus \input supp-mis.tex \relax \fi
+
+\unprotect
+
+%D \TEX\ provides 256 \DIMENSIONS\ and 256 \SKIPS. In \CONTEXT\
+%D this is no problem, but in packages that have many
+%D authors, one can be quite sure that a lot of \DIMENSIONS\ are
+%D allocated. Packages that use \PICTEX\ can therefore run out
+%D of \DIMENSIONS\ quite fast. This module was written as a
+%D reaction to persistent problems with loading \PPCHTEX\ in
+%D \LATEX\ and \PICTEX\ deserves a solution. I therefore
+%D dedicate this module to Tobias Burnus and Dirk Kuypers, who
+%D use \PPCHTEX\ in a \LATEX\ environment and suggested a lot
+%D of extensions to the repertoire of \PPCHTEX\ commands.
+%D
+%D This module presents a solution that is quite effective: all
+%D \DIMENSIONS\ are drawn from the pool of \DIMENSIONS\ and
+%D \SKIPS, depending on the availability. This is possible
+%D because \DIMENSIONS\ are \SKIPS\ without a glue component.
+%D Therefore we can use \SKIPS\ as \DIMENSIONS. However, some
+%D incompatibility can result from assignments that look like:
+%D
+%D \starttyping
+%D \somedimen=\someskip
+%D \stoptyping
+%D
+%D In such cases the \DIMENSION\ equals the fixed part of the
+%D \SKIP\ or in other words: this assignment strips off the
+%D glue. Because \PICTEX\ uses no glue components, I thought
+%D I could interchange both register types without problems,
+%D but alas, this didn't hold for all \DIMENSIONS.
+
+%D In \PLAIN\ \TEX\ the allocation macros are defined with (as)
+%D \type{\outer}. This means that they cannot appear inside
+%D macros, not even in an indirect way. We therefore have to
+%D redefine both \type{\newdimen} and \type{\newskip} to
+%D non||\type{\outer} alternatives. In most macro packages this
+%D redefinition already took place. We save the original
+%D meanings, so we can restores them afterwards.
+
+% \def\temporarynewdimen {\alloc@1\dimen\dimendef\insc@unt}
+% \def\temporarynewskip {\alloc@2\skip \skipdef \insc@unt}
+
+\let\normalnewdimen \newdimen
+\let\normalnewskip \newskip
+
+\let\temporarynewdimen\newdimen
+\let\temporarynewskip \newskip
+
+%D Here comes the trick. Depending on how many \DIMENSIONS\ and
+%D \SKIPS\ are allocated, the \type{\newdimen} assigns a
+%D \DIMENSIONS\ or \SKIP. \PLAIN\ \TEX\ allocates 15 \DIMENSIONS\
+%D and 17 \SKIPS. After loading \PICTEX, 71 \DIMENSIONS\ and
+%D and 71 \SKIPS\ are allocated. Indeed, \PICTEX\ needs 110
+%D \DIMENSIONS !
+%D
+%D \starttyping
+%D \def\newdimen
+%D {\ifnum\count11>\count12
+%D \let\next\temporarynewskip
+%D \else
+%D \let\next\temporarynewdimen
+%D \fi
+%D \next}
+%D \stoptyping
+%D
+%D When I was testing a new version of \PPCHTEX\ in \PLAIN\
+%D \TEX\ I had to find out that this exchange of registers
+%D sometimes leads to unwanted results. It took me some hours
+%D to find out that the source of errors originated in
+%D constructions like:
+%D
+%D \starttyping
+%D \ifdim\DimenOne<\DimenTwo whatever you want \else or not \fi
+%D \stoptyping
+%D
+%D When \type{\DimenOne} is a \SKIP\ and \type{\DimenTwo} is a
+%D \DIMENSION, \TEX\ scans for some optional glue component,
+%D like in:
+%D
+%D \starttyping
+%D \skip0=\dimen0 plus 10pt minus 5pt
+%D \stoptyping
+%D
+%D The most robust solution to this problem is:
+%D
+%D \starttyping
+%D \ifdim\DimenOne<\DimenTwo\relax right \else wrong \fi
+%D \stoptyping
+%D
+%D Some close reading of the \PICTEX\ source however learned me
+%D that this problem could be solved best by just honoring the
+%D allocation of \DIMENSIONS\ when the name of the macro
+%D explictly stated the character sequence \type{dimen}. A next
+%D implementation therefore automatically declared all
+%D \DIMENSIONS\ with this sequence in their names with
+%D \type{\dimen}. Again I was too optimistic, so now we do it
+%D this way (the comments are from \PICTEX, which like \TABLE,
+%D is an example of a well documented package):
+
+\temporarynewdimen\!dimenA %.AW.X.DVEUL..OYQRST
+\temporarynewdimen\!dimenB %....X.DVEU...O.QRS.
+\temporarynewdimen\!dimenC %..W.X.DVEU......RS.
+\temporarynewdimen\!dimenD %..W.X.DVEU....Y.RS.
+\temporarynewdimen\!dimenE %..W........G..YQ.S.
+\temporarynewdimen\!dimenF %...........G..YQ.S.
+\temporarynewdimen\!dimenG %...........G..YQ.S.
+\temporarynewdimen\!dimenH %...........G..Y..S.
+\temporarynewdimen\!dimenI %...BX.........Y....
+\temporarynewdimen\!dxpos %..W......U..P....S.
+\temporarynewdimen\!dypos %..WB.....U..P......
+\temporarynewdimen\!xloc %..WB.....U.......S.
+\temporarynewdimen\!xpos %..........L.P..Q.ST
+\temporarynewdimen\!yloc %..WB.....U.......S.
+\temporarynewdimen\!ypos %..........L.P..Q.ST
+\temporarynewdimen\!zpt %.AWBX.DVEULGP.YQ.ST
+
+%D Tobias tested this module in all kind of \LATEX\ dialects
+%D so we were able to find out that we also needed to declare:
+
+\temporarynewdimen\linethickness
+
+%D After all, the new definition of \type{\newdimen} became:
+
+\def\newdimen#1%
+ {\ifx#1\undefined
+ \ifnum\count11>\count12\relax
+ \temporarynewskip#1\relax
+ \else
+ \temporarynewdimen#1\relax
+ \fi
+ %\edef\ascii{\meaning#1}%
+ %\immediate\write20{\string#1 becomes \ascii}%
+ \else
+ %\edef\ascii{\meaning#1}%
+ %\immediate\write20{\string#1 already is \ascii}%
+ \fi}
+
+% This macro is as unreadable, inefficient and as compact as
+% can be, but uses no extra hash entries, which sometimes are
+% scarce too. A more readable alternative, that also takes
+% explicit \SKIPS\ into account, is included in the source.
+%
+% \def\doifregisterpreferenceelse#1#2#3#4%
+% {\def\dodoifregisterpreferenceelse##1#1##2##3\war{\if##2@}%
+% \expandafter\dodoifregisterpreferenceelse\string#2#1@@\war
+% #4%
+% \else
+% #3%
+% \fi}
+%
+% \def\newdimen#1%
+% {\bgroup
+% \escapechar=-1
+% \expandafter\doifregisterpreferenceelse\expandafter{\string\dimen}#1
+% {\egroup
+% \temporarynewdimen#1}
+% {\expandafter\doifregisterpreferenceelse\expandafter{\string\skip}#1
+% {\egroup
+% \temporarynewskip#1}
+% {\egroup
+% \ifnum\count11>\count12
+% \temporarynewskip#1\relax
+% \else
+% \temporarynewdimen#1\relax
+% \fi}}}
+
+%D Curious readers can still find the previous solution in
+%D the source. The next macro is used instead of
+%D \type{\input}. This macro also reports some statistics.
+
+\def\dimeninput#1 %
+ {\message{[before: d=\the\count11,s=\the\count12]}%
+ \input #1 \relax
+ \message{[after: d=\the\count11,s=\the\count12]}}%
+
+%D Now we can load \PICTEX:
+
+\loadpictex
+
+%D Finally we restore the old definitions of \type{\newdimen}
+%D and \type{\newskip}:
+
+\let\newdimen=\normalnewdimen
+\let\newskip =\normalnewskip
+
+%D and just hope for the best.
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-pstricks.mkii b/tex/context/modules/mkii/m-pstricks.mkii
new file mode 100644
index 000000000..d41f19871
--- /dev/null
+++ b/tex/context/modules/mkii/m-pstricks.mkii
@@ -0,0 +1,127 @@
+%D \module
+%D [ file=m-pstricks,
+%D version=1997.01.15,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PSTRICKS\ Connections,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% pstricks is not supported in context mkii (it's no problem doing that
+% but as we also need to support latex it would become quite messy so for
+% context we use metapost and for latex pstricks)
+
+%M \usemodule[pstric]
+
+\letvalue{@unused}\plussixteen
+\letvalue{alloc@}\gobblefivearguments
+
+\chardef\oldbarcode\the\catcode`\| \catcode`\|=12
+
+\def\loadpstrickscolors#1%
+ {\pushmacro\dodefinecolor
+ \pushmacro\dodefinepalet
+ \pushmacro\dodefinecolorgroup
+ \def\dodefinecolor[##1][##2]%
+ {\doifassignmentelse{##2}
+ {\getparameters[pstricks][r=0,g=0,b=0,##2]%
+ \expanded{\newrgbcolor{##1}{{\pstricksr} {\pstricksg} {\pstricksb}}}}%
+ {}}%
+ \def\dodefinepalet [##1][##2]{}%
+ \def\dodefinecolorgroup[##1][##2][##3]{}%
+ \writestatus{pstricks}{loading colors from #1}%
+ \input #1 \relax
+ \popmacro\dodefinecolorgroup
+ \popmacro\dodefinepalet
+ \popmacro\dodefinecolor}
+
+\doifelse{\jobsuffix}{dvi}
+ {\input multido \relax
+ \input pstricks \relax
+ \input pst-plot \relax
+ \loadpstrickscolors{colo-rgb.mkii}}
+ {\writestatus{pstricks}{using indirect method; enable write18}}
+
+\catcode`\|=\oldbarcode
+
+\def\loadpstricksmodule[#1]%
+ {\chardef\oldbarcode\the\catcode`\|
+ \catcode`\|=12
+ \readfile{#1}{}{}%
+ \catcode`\|=\oldbarcode}
+
+%D The next piece of code is for John Culleton who suggested to
+%D handle \PSTRICKS\ in a similar fashion as \METAPOST, i.e.\
+%D using a child process. For the moment there is no support
+%D for passing environments, so these should be called
+%D explicitly inside this environment.
+
+\unprotect
+
+%D \startPSTRICKS[offset=2pt] ... \stopPSTRICKS
+%D
+%D works in both dvi and pdf mode
+%D
+%D % \usemodule[pstric]
+%D
+%D \startPSTRICKS
+%D \pspicture(0,0)(10,10)
+%D \dorecurse{10}{\psline(0,0)(\recurselevel,10)}
+%D \dorecurse{10}{\psline(0,0)(10,\recurselevel)}
+%D \endpspicture
+%D \stopPSTRICKS
+
+\def\startPSTRICKS
+ {\dosingleempty\dostartPSTRICKS}
+
+% \ifx\startTEXapplication\undefined
+%
+% \long\def\dostartPSTRICKS[#1]#2\stopPSTRICKS
+% {\doifelse{\jobsuffix}{dvi}
+% {#2}
+% {\bgroup
+% \setbuffer[pstricks]%
+% \usemodule[pstric]%
+% \setbox\scratchbox\hbox{#2}%
+% % There is probably a nicer way to handle this
+% \immediate\openout\scratchwrite=\bufferprefix dim.tmp
+% \immediate\write\scratchwrite{\dimen0=\the\ht\scratchbox}%
+% \immediate\write\scratchwrite{\dimen2=\the\wd\scratchbox}%
+% \immediate\closeout\scratchwrite
+% % Quick and dirty
+% \startTEXpage[#1]\box\scratchbox\stopTEXpage
+% \endbuffer
+% % Here we go!
+% %\immediate\write18{texexec \bufferprefix pstricks.tmp --once --batch}%
+% %\immediate\write18{dvips -G0 -Ppdf \bufferprefix pstricks -o}%
+% %\immediate\write18{ps2pdf \bufferprefix pstricks.ps \bufferprefix pstricks.pdf}%
+% \executesystemcommand{texexec \bufferprefix pstricks.tmp --once --batch}%
+% \executesystemcommand{dvips -G0 -Ppdf \bufferprefix pstricks -o}%
+% \executesystemcommand{texmfstart pstopdf \bufferprefix pstricks.ps \bufferprefix pstricks.pdf}%
+% % We pick up the dimensions from the scratch file.
+% \readlocfile{\bufferprefix pstricks-dim.tmp}{}{}%
+% % Since the graphic is put on a page (sigh) by dvips/gs
+% % we need to shift it around a bit.
+% \setbox\scratchbox\hbox
+% {\externalfigure[\bufferprefix pstricks.pdf][\c!object=\v!no]}%
+% \setbox\scratchbox\hbox
+% {\lower\ht\scratchbox\hbox{\raise\dimen2\box\scratchbox}}%
+% \wd\scratchbox\dimen0
+% \ht\scratchbox\dimen2
+% \dp\scratchbox\zeropoint
+% \box\scratchbox
+% \egroup}}
+%
+% \fi
+
+\long\def\dostartPSTRICKS[#1]#2\stopPSTRICKS
+ {\doifelse{\jobsuffix}{dvi} % will some day move to app as switch
+ {\hbox{#2}}
+% {\startTEXapplication[#1]{\usemodule[pstric]}#2\stopTEXapplication}}
+ {\startTEXapplication[#1]{}#2\stopTEXapplication}}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-r.mkii b/tex/context/modules/mkii/m-r.mkii
new file mode 100644
index 000000000..c2cb7ba88
--- /dev/null
+++ b/tex/context/modules/mkii/m-r.mkii
@@ -0,0 +1,174 @@
+%D \module
+%D [ file=m-r,
+%D version=2006.06.06,
+%D title=\CONTEXT\ Modules,
+%D subtitle=R Support,
+%D author={Johan Sandblom \& Hans Hagen},
+%D date=\currentdate,
+%D copyright={Johan Sandblom \& Hans Hagen}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D The following R-processor is a variation on Johan Sandblom's
+%D prototype.
+%D
+%D We can combine both variants in one macro definition. Also, we
+%D can minimize the number of runs by checking for a change.
+
+%D JS: The call to R has \type {-q} in order to prevent banner,
+%D \type {--save} to make sure it saves the workspace after the run,
+%D \type {--restore} to make sure it reads any workspace from a
+%D previous session.
+
+%D An easier and better solution is to use the buffering mechanisms:
+
+\def\Rbufferprefix{r-}
+
+\newcounter\nofRfiles
+
+\def\Rfile{\TEXbufferfile{\Rbufferprefix\nofRfiles}}
+
+\def\startR
+ {\doglobal\increment\nofRfiles
+ \dostartbuffer[\Rbufferprefix\nofRfiles][startR][stopR]}
+
+\def\stopR
+ {\doifmode{*\v!first}\runR
+ \typefile{\Rfile.out}}
+
+\def\startRhidden
+ {\doglobal\increment\nofRfiles
+ \dostartbuffer[\Rbufferprefix\nofRfiles][startRhidden][stopRhidden]}
+
+\def\stopRhidden
+ {\doifmode{*\v!first}\runR}
+
+\def\runR
+ {\executesystemcommand{texmfstart
+ --ifchanged=\Rfile\space --direct R
+ CMD BATCH -q --save --restore \Rfile\space \Rfile.out}}
+
+\protect \doifnotmode{demo}{\endinput}
+
+% Johan's test file:
+
+\usemodule[r]
+
+\def\R{R}
+
+\setupcolors[state=start]
+
+\setuptyping
+ [Rtype]
+ [color=darkgreen]
+
+\starttext
+
+First a test of whether the workspace is persistent:
+bla
+
+\startR
+a <- "bla"
+b <- "blabla"
+ls()
+\stopR
+
+One \R run ends, another begins.
+
+\startR
+ls()
+\stopR
+
+Now follows a hidden \R run which cleans the R workspace
+
+\startRhidden
+rm(list=ls())
+save.image()
+\stopRhidden
+
+What is in the workspace now?
+
+\startR
+ls()
+\stopR
+
+Then a small test of generating a graphic, in this case a pdf
+\startR
+ushape <- c(rexp(500000), 12-rexp(500000))
+pdf("ushape.pdf")
+par(mfrow=c(1,2))
+hist(ushape)
+plot(density(ushape), main="Density")
+dev.off()
+\stopR
+
+The graphic \type{ushape.pdf} can be included in the standard \CONTEXT\ way
+\startbuffer
+\placefigure{An ugly distribution}{\externalfigure[ushape]}
+\stopbuffer
+\typebuffer
+\getbuffer
+
+\startR
+x <- rnorm(900)
+y <- rexp(900)
+# test comment
+f <- gl(9,9,900)
+summary(aov(y~x+Error(f)))
+library(lattice)
+pdf("lattice.pdf")
+xyplot(y~x|f)
+dev.off()
+\stopR
+
+With \type{Sweave} lattice graphics calls must be enclosed in
+\type{print()} statements but that is not necessary here.
+
+\startbuffer
+\placefigure[here]{Lattice graphics}{\externalfigure[lattice]}
+\stopbuffer
+\typebuffer
+\getbuffer
+
+A test string with nasty characters. In \R, the result of a statement
+is not printed by default. Enclosing the statement in parentheses,
+however causes the parser to see only the value of the statement and
+applying the \type{print()} method.
+\startR
+(test <- ".*\\\\ [[{[{]{[{[{}\]\}=?!+%#|<|>@$")
+cat(test)
+\stopR
+
+A combination
+\startbuffer
+\placefigure{A combination of two previously used graphics}{
+\startcombination[2*1]
+ {\externalfigure[ushape][width=.4\textwidth]}{The first graphic, rescaled}
+ {\externalfigure[lattice][width=.4\textwidth]}{The second graphic, rescaled}}
+\stopcombination
+\stopbuffer
+\typebuffer
+\getbuffer
+
+Testing a function definition.
+
+\startR
+a.df <- data.frame(a=1:2, b=rnorm(2))
+a.df$a
+testfunction <- function(a=NULL, ...) {
+ for(i in 1:length(a)) {
+ gsub(a[[i]], "([a-r]|[A-R])", "bla")}
+ print(a)}
+\stopR
+
+What is in the workspace now?
+
+\startR
+ls()
+\stopR
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-steps.mkii b/tex/context/modules/mkii/m-steps.mkii
new file mode 100644
index 000000000..e6bd45548
--- /dev/null
+++ b/tex/context/modules/mkii/m-steps.mkii
@@ -0,0 +1,837 @@
+%D \module
+%D [ file=m-steps,
+%D version=2001.05.28,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Step Charts \& Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D When I need this module, I will reimplement it by using the new
+%D sometxt macro. Anyhow, it reflects the state of 2001.
+
+\unprotect
+
+% temp hack :
+
+% \ifx\v!kleinkorps\undefined \let\v!kleinkorps\setsmallbodyfont \fi
+
+% end of hack
+
+\definecolor [STEPlinecolor] [s=.5]
+\definecolor [STEPframecolor] [s=.7]
+\definecolor [STEPbackgroundcolor] [s=.9]
+
+\def\@@STPF{@@STPF} % frames
+
+\def\@@STPC{@@STPC} % charts
+\def\@@STPT{@@STPT} % tables
+
+\def\@@STEC{@@STEC} % cells
+\def\@@STET{@@STET} % tables
+\def\@@STEL{@@STEL} % lines
+
+\def\setupSTEPcharts{\dodoubleargument\getparameters[\@@STPC]}
+\def\setupSTEPtables{\dodoubleargument\getparameters[\@@STPT]}
+\def\setupSTEPcells {\dodoubleargument\getparameters[\@@STEC]}
+\def\setupSTEPtexts {\dodoubleargument\getparameters[\@@STET]}
+\def\setupSTEPlines {\dodoubleargument\getparameters[\@@STEL]}
+
+\setupSTEPcharts
+ [\c!before=\blank,
+ \c!after=\blank,
+ %\c!distance=.25em, % nvt
+ \c!hoffset=1em,
+ \c!voffset=1ex,
+ \c!method=1,
+ \c!height=2ex,
+ \c!offset=.15\bodyfontsize]
+
+\setupSTEPtables
+ [\c!before=\blank,
+ \c!after=\blank,
+ \c!distance=.25em,
+ %\c!hoffset=1em, % nvt
+ \c!voffset=1ex,
+ \c!method=1,
+ \c!width=4em,
+ \c!offset=.15\bodyfontsize]
+
+\setupSTEPcells
+ [\c!alternative=24,
+ \c!background=\v!color,
+ \c!backgroundcolor=STEPbackgroundcolor,
+ \c!rulethickness=.1\bodyfontsize,
+ \c!framecolor=STEPframecolor,
+ \c!offset=.25\bodyfontsize,
+ \c!style=,
+ \c!color=]
+
+\setupSTEPtexts
+ [\c!alternative=24,
+ \c!background=\v!color,
+ \c!backgroundcolor=STEPbackgroundcolor,
+ \c!rulethickness=.1\bodyfontsize,
+ \c!framecolor=STEPframecolor,
+ \c!offset=.25\bodyfontsize,
+ \c!style=\v!smallbodyfont,
+ \c!color=]
+
+\setupSTEPlines
+ [\c!alternative=1,
+ \c!rulethickness=.15\bodyfontsize,
+ \c!color=STEPlinecolor]
+
+\def\initializeSTEP
+ {\initializeSTET \initializeSTEC \initializeSTEL}
+
+\def\initializeSTPC
+ {\freezedimenmacro\@@STPCoffset
+ \startMPdrawing
+ line_v_offset := \@@STPCoffset ;
+ line_method := \@@STPCmethod ; % only charts
+ \stopMPdrawing}
+
+\def\initializeSTPT
+ {\freezedimenmacro\@@STPToffset
+ \startMPdrawing
+ line_h_offset := \@@STPToffset ;
+ line_method := \@@STPTmethod ; % only charts
+ \stopMPdrawing}
+
+\def\initializeSTET
+ {\freezedimenmacro\@@STETrulethickness
+ \freezedimenmacro\@@STEToffset}
+
+\def\initializeSTEC
+ {\freezedimenmacro\@@STECrulethickness
+ \freezedimenmacro\@@STECoffset}
+
+\def\initializeSTEL
+ {\freezedimenmacro\@@STELrulethickness}
+
+%D ...
+
+\presetlocalframed[\@@STPF]
+
+\def\@@stepcell#1%
+ {\doattributes\@@STEC\c!style\c!color
+ {\localframed
+ [\@@STPF][\c!offset=\@@STECoffset,\c!frame=\v!off]
+ {\ignorespaces#1\unskip}}}
+
+\def\@@stepfake#1%
+ {\doattributes\@@STEC\c!style\c!color
+ {\ignorespaces#1\unskip}}
+
+\def\@@steptext#1%
+ {\doattributes\@@STET\c!style\c!color
+ {\localframed
+ [\@@STPF][\c!offset=\@@STEToffset,\c!frame=\v!off]
+ {\ignorespaces#1\unskip}}}
+
+%D The first attempt was purely \METAPOST\ based and spawned
+%D the typesetting to the \METAFUN\ handler. This method
+%D collects the cells, and directly passes them on to
+%D \METAPOST. This method is the cleanest, but has the
+%D disadvantage that one cannot embed hyperlinks or document
+%D dependent definitions in the cells. The implementation
+%D roughly looks as follows:
+%D
+%D \starttyping
+%D \def\startSTEPchart%
+%D {\bgroup
+%D \startMPdrawing
+%D input mp-step.mpii ; begin_step_chart ;
+%D \stopMPdrawing
+%D \initializeSTEP
+%D \let\cells\stepchartcells \def\cell{\cells{}}%
+%D \let\texts\stepcharttexts \def\text{\texts{}}}
+%D
+%D \def\stepchartcells#1#2%
+%D {\setMPtext{tdummy}{\strut\ignorespaces#1\unskip}% beter etex/btex
+%D \setMPtext{bdummy}{\strut\ignorespaces#2\unskip}% beter etex/btex
+%D \startMPdrawing
+%D set_step_chart_cells(\MPstring{tdummy},\MPstring{bdummy}) ;
+%D \stopMPdrawing}
+%D
+%D \def\stepcharttexts#1#2%
+%D {\setMPtext{tdummy}{\strut\ignorespaces#1\unskip}% beter etex/btex
+%D \setMPtext{bdummy}{\strut\ignorespaces#2\unskip}% beter etex/btex
+%D \startMPdrawing
+%D set_step_chart_texts(\MPstring{tdummy},\MPstring{bdummy}) ;
+%D \stopMPdrawing}
+%D
+%D \def\stopSTEPchart
+%D {\startMPdrawing
+%D end_step_chart ;
+%D \stopMPdrawing
+%D \MPdrawingdonetrue
+%D \getMPdrawing
+%D \resetMPdrawing
+%D \egroup}
+%D \stoptyping
+%D
+%D This method has the advantage that it does the job in
+%D (virtually) one pass, while the next methods need multiple
+%D passes: one to build the table, another to synchronize the
+%D positions, and a third one beause the dimensions may have
+%D changed. The last pass is a result from the fact that
+%D positions are related to the page.
+%D
+%D The second attempt was based on tabulations and used the
+%D build in position tracking mechanism, which uses two
+%D position nodes per cell.
+%D
+%D This method collects the content in token list registers
+%D and build a table from them. In the collecting pass, the
+%D graphics are build stepwise. We need to collect because the
+%D order of definitions is not the same as the order of
+%D typesetting. We show this alternative too because it
+%D demonstrates how to apply backgrounds to table cells.
+%D
+%D \starttyping
+%D \newtoks\stepsonetop \newtoks\stepstwotop
+%D \newtoks\stepsonebot \newtoks\stepstwobot
+%D \stoptyping
+%D
+%D During the collecting phase, we temporarily have to
+%D increment the name space counter.
+%D
+%D \starttyping
+%D \def\startSTEPchart%
+%D {\bgroup
+%D \resetMPdrawing
+%D \advance\noftabpositions\plusone % begin of preroll
+%D \startMPdrawing
+%D input mp-step.mpii ;
+%D begin_step_chart ;
+%D \stopMPdrawing
+%D \initializeSTEP
+%D \newcounter\cellcounter
+%D \stepsonetop\emptytoks \chardef\somesteponetop=1
+%D \stepsonebot\emptytoks \chardef\somesteponebot=1
+%D \stepstwotop\emptytoks \chardef\somesteptwotop=1
+%D \stepstwobot\emptytoks \chardef\somesteptwobot=1
+%D \let\cells\stepchartcells \def\cell{\cells{}}%
+%D \let\texts\stepcharttexts \def\text{\texts{}}}
+%D \stoptyping
+%D
+%D Now we collect the steps and texts, and in the process the
+%D graphic is built. Then we continue with building the table.
+%D
+%D Watch how we anchor the graphic to the main table box. This
+%D is needed since the graphic may be larger than the table
+%D itself. Actually, these small point took me the most time to
+%D digest, even with the right tools (anchors) already in
+%D place.
+%D
+%D \starttyping
+%D \def\stopSTEPchart
+%D {\splittabulatefalse
+%D \insidefloattrue
+%D \startMPdrawing
+%D nofcells := \cellcounter ;
+%D end_step_chart ;
+%D anchor_box(\MPpos{\tbPOSprefix origin}) ;
+%D \stopMPdrawing
+%D \MPdrawingdonetrue
+%D \advance\noftabpositions\minusone % end of preroll
+%D \setbox0=\vbox
+%D {\getMPdrawing}
+%D \resetMPdrawing
+%D \increment(\cellcounter,\cellcounter)\decrement\cellcounter
+%D \setbox2=\vbox
+%D {\definetabulate[chart][|*{\cellcounter}{ck0|}] % k0 nills space
+%D \startchart
+%D \ifcase\somesteptwotop \the\stepstwotop \NC \NR \noalign{\kern2ex} \fi
+%D \ifcase\somesteponetop \the\stepsonetop \NC \NR \noalign{\kern2ex} \fi
+%D \ifcase\somesteponebot \the\stepsonebot \NC \NR \noalign{\kern2ex} \fi
+%D \ifcase\somesteptwobot \the\stepstwobot \NC \NR \noalign{\kern2ex} \fi
+%D \noalign{\kern-2ex}%
+%D \stopchart}
+%D \hbox
+%D {\scratchdimen\wd0
+%D \advance\scratchdimen \MPllx bp
+%D \raise\MPlly bp\box0
+%D \hskip-\scratchdimen
+%D \hpos{\tbPOSprefix origin}{\box2}}
+%D \egroup}
+%D \stoptyping
+%D
+%D The steps and texts fill the (at most 4) lines that make up
+%D the table. We also feed the (automatically registerd) cell
+%D dimensions to the graphic backend.
+%D
+%D \starttyping
+%D \newcounter\cellcounter
+%D \newcounter\textcounter
+%D
+%D \def\stepchartcells#1#2%
+%D {\doloop
+%D {\ifnum\cellcounter>\textcounter
+%D \stepcharttexts{}{}%
+%D \else
+%D \exitloop
+%D \fi}%
+%D \increment\cellcounter
+%D \doifelsenothing{#1}
+%D {\startMPdrawing
+%D cells[t][\cellcounter] := origin ;
+%D \stopMPdrawing
+%D \appendtoks\NC\NC\to\stepsonetop}
+%D {\chardef\somesteponetop=0
+%D \edef\stepidentifier{\cellcounter-t-c}%
+%D \startMPdrawing
+%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier},
+%D \MPpos{e:\tbPOSprefix\stepidentifier}) ;
+%D cells[t][\cellcounter] := pxy ;
+%D \stopMPdrawing
+%D \@EA\appendtoks\@EA\stepidentifierposition\@EA{\stepidentifier}#1\NC\to\stepsonetop}%
+%D \doifelsenothing{#2}
+%D {\startMPdrawing
+%D cells[b][\cellcounter] := origin ;
+%D \stopMPdrawing
+%D \appendtoks\NC\NC\to\stepsonebot}
+%D {\chardef\somesteponebot=0
+%D \edef\stepidentifier{\cellcounter-b-c}%
+%D \startMPdrawing
+%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier},
+%D \MPpos{e:\tbPOSprefix\stepidentifier}) ;
+%D cells[b][\cellcounter] := pxy ;
+%D \stopMPdrawing
+%D \@EA\appendtoks\@EA\stepidentifierposition\@EA{\stepidentifier}#2\NC\to\stepsonebot}}
+%D
+%D \def\stepcharttexts#1#2% \cellcounter = nofcells
+%D {\increment\textcounter
+%D \doifelsenothing{#1}
+%D {\startMPdrawing
+%D texts[t][\cellcounter][\textcounter] := origin ;
+%D \stopMPdrawing
+%D \appendtoks\NC\NC\to\stepstwotop}
+%D {\chardef\somesteptwotop=0
+%D \edef\stepidentifier{\cellcounter-\textcounter-t-t}%
+%D \startMPdrawing
+%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier},
+%D \MPpos{e:\tbPOSprefix\stepidentifier}) ;
+%D texts[t][\cellcounter][\textcounter] := pxy ;
+%D \stopMPdrawing
+%D \@EA\appendtoks\@EA\NC\@EA\textcellposition\@EA{\stepidentifier}#1\to\stepstwotop}%
+%D \doifelsenothing{#2}
+%D {\startMPdrawing
+%D texts[b][\cellcounter][\textcounter] := origin ;
+%D \stopMPdrawing
+%D \appendtoks\NC\NC\to\stepstwobot}
+%D {\chardef\somesteptwobot=0
+%D \edef\stepidentifier{\cellcounter-\textcounter-b-t}%
+%D \startMPdrawing
+%D initialize_area(\MPpos{b:\tbPOSprefix\stepidentifier},
+%D \MPpos{e:\tbPOSprefix\stepidentifier}) ;
+%D texts[b][\cellcounter][\textcounter] := pxy ;
+%D \stopMPdrawing
+%D \@EA\appendtoks\@EA\NC\@EA\textcellposition\@EA{\stepidentifier}#2\to\stepstwobot}}
+%D \stoptyping
+%D
+%D Here are the hooks that take care of calculating the cell
+%D dimensions.
+%D
+%D \starttyping
+%D \def\textcellposition#1{\GSC[#1:text]}
+%D \def\stepidentifierposition#1{\GSC[#1:step]}
+%D \stoptyping
+%D
+%D We abandoned this method after some testing and went for
+%D a third one. It was this third method that evolved into the
+%D current mechanism.
+%D
+%D Since this method was not that efficient, a third one was
+%D implemented, which used one position per cell. So,
+%D
+%D \blank {\bf Here starts the real implementation!} \blank
+%D
+%D Because we want to build one graphic only we need to store
+%D the graphic directives. We also need to collect the cells,
+%D which are not defined in the order they show up. This
+%D solution uses multiple passes over the definitions. First
+%D the cells and texts are processed and the associated
+%D graphics are defined in the \METAPOST\ file. Next the
+%D lines are flushed. We need to do that in a second pass,
+%D because in order to determine the nature of the line,
+%D \METAPOST\ needs to know if the start and end cells exist.
+%D This need comes from the fact that we store the shapes
+%D and lines kind of directly with their associated colors and
+%D types, so that we can change the settings in between. So,
+%D changing for instance the line color, can take place
+%D locally.
+
+\newbox\stepboxone \newbox\stepboxtwo
+\newbox\textboxone \newbox\textboxtwo
+
+%D We need to define a dedicated name space counter.
+
+\newcounter\currentstepchart
+
+\def\stepchartprefix{@sc@-\currentstepchart-}
+
+%D Next we define the initialization part of the macros.
+
+\newcounter\cellcounter
+\newcounter\textcounter
+
+\def\startSTEPchart
+ {\dosingleempty\dostartSTEPchart}
+
+\long\def\dostartSTEPchart[#1]#2\stopSTEPchart
+ {\ifinsidefloat
+ \else
+ \whitespace
+ \@@STPCbefore
+ \startbaselinecorrection
+ \setlocalhsize
+ \noindent
+ \fi
+ \vbox\bgroup
+ \setupSTEPcharts[#1]%
+ \forgetall
+ \pushMPdrawing
+ \resetMPdrawing
+ \doglobal\increment\currentstepchart
+ \startMPdrawing
+ input mp-step.mpii ;
+ begin_step_chart ;
+ \stopMPdrawing
+ \initializeSTEP
+ \initializeSTPC
+ \global\chardef\somestepboxone\plusone
+ \global\chardef\sometextboxone\plusone
+ \global\chardef\somestepboxtwo\somestepboxone
+ \global\chardef\sometextboxtwo\sometextboxone
+ \def\startlines{\bgroup\setupSTEPlines}%
+ \def\stoplines {\egroup}%
+ \def\cells{\dosingleempty\dostepchartcells}
+ \def\texts{\dosingleempty\dostepcharttexts}
+ \def\cell {\dosingleempty\docell}%
+ \def\text {\dosingleempty\dotext}%
+ \def\docell[##1]{\dostepchartcells[##1]{}}%
+ \def\dotext[##1]{\dostepcharttexts[##1]{}}
+ \doglobal\newcounter\cellcounter
+ \doglobal\newcounter\textcounter
+ \let\dostepchartcells\doSTEPchartcellsA
+ \let\dostepcharttexts\doSTEPcharttextsA
+ {#2} % pass one: cells and texts {} keeps setting local
+ \startMPdrawing
+ nofcells := \cellcounter ;
+ analyze_step_chart ;
+ \stopMPdrawing
+ \doglobal\newcounter\cellcounter
+ \doglobal\newcounter\textcounter
+ \let\dostepchartcells\doSTEPchartcellsB
+ \let\dostepcharttexts\doSTEPcharttextsB
+ {#2} % pass two: lines
+ \startMPdrawing
+ end_step_chart ;
+ % if box_found(\MPpos{\stepchartprefix origin}) :
+ % initialize_box(\MPpos{\stepchartprefix origin}) ;
+ % draw pxy ;
+ % fi ;
+ anchor_box(\MPpos{\stepchartprefix origin}) ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \doifelse\@@STPCmethod{0}
+ {\setbox0\null}
+ {\setbox0\vbox{\MPstaticgraphictrue\getMPdrawing}}%
+ \resetMPdrawing
+ \setbox2\vbox
+ {\offinterlineskip
+ \scratchdimen\@@STPCheight
+ \advance\scratchdimen\@@STPCoffset
+ \advance\scratchdimen\@@STPCoffset
+ \ifcase\sometextboxone \box\textboxone \vskip\scratchdimen \fi
+ \ifcase\somestepboxone \box\stepboxone \vskip\@@STPCvoffset \fi
+ \ifcase\somestepboxtwo \box\stepboxtwo \vskip\scratchdimen \fi
+ \ifcase\sometextboxtwo \box\textboxtwo \vskip\@@STPCvoffset \fi
+ \global\setbox\stepboxone\emptybox \global\setbox\stepboxtwo\emptybox % needed indeed
+ \global\setbox\textboxone\emptybox \global\setbox\textboxtwo\emptybox % needed indeed
+ %\kern-\scratchdimen % no, instead:
+ \vskip-\lastskip}
+ \hbox
+ {\scratchdimen\wd0
+ \advance\scratchdimen \MPllx bp
+ \raise\MPlly bp\box0
+ \hskip-\scratchdimen
+ \hpos{\stepchartprefix origin}{\box2}}%
+ \popMPdrawing
+ \egroup
+ \ifinsidefloat \else \stopbaselinecorrection \@@STPCafter \fi}
+
+%D The next macro looks more complicated than it is. We collect
+%D the cells in boxes. Before adding a new step cell, we padd
+%D the text rows. After adding the step cells, we flush text
+%D cells that are defined but not yet processed.
+
+\def\doSTEPchartcellsA[#1]#2#3%
+ {% synchronize texts
+ \doSTEPchartcellsAB[#1]{#2}{#3}%
+ % package steps
+ \setbox0\hbox{\doifsomething{#2}{\@@stepcell{#2}}}%
+ \setbox2\hbox{\doifsomething{#3}{\@@stepcell{#3}}}%
+ \ifdim\wd0>\zeropoint \!!doneafalse \else \!!doneatrue \fi
+ \ifdim\wd2>\zeropoint \!!donebfalse \else \!!donebtrue \fi
+ \ifdim\wd0>\wd2
+ \setbox2\hbox to \wd0{\hss\box2\hss}%
+ \else
+ \setbox0\hbox to \wd2{\hss\box0\hss}%
+ \fi
+ \if!!donea
+ \startMPdrawing
+ cells[t][\cellcounter] := nullpicture ;
+ \stopMPdrawing
+ \else
+ \global\chardef\somestepboxone\zerocount
+ \edef\stepidentifier{\stepchartprefix\cellcounter-t-c}%
+ \setbox0\hbox{\hpos{\stepidentifier}{\box0}}%
+ \bgroup
+ \iffirstargument\setupSTEPcells[#1]\fi\initializeSTEC
+ \startMPdrawing
+ initialize_box(\MPpos{\stepidentifier}) ;
+ cells[t][\cellcounter] := \MPcellsgraphic ;
+ \stopMPdrawing
+ \egroup
+ \fi
+ \if!!doneb
+ \startMPdrawing
+ cells[b][\cellcounter] := nullpicture ;
+ \stopMPdrawing
+ \else
+ \global\chardef\somestepboxtwo\zerocount
+ \edef\stepidentifier{\stepchartprefix\cellcounter-b-c}%
+ \setbox2\hbox{\hpos{\stepidentifier}{\box2}}%
+ \bgroup
+ \iffirstargument\setupSTEPcells[#1]\fi\initializeSTEC
+ \startMPdrawing
+ initialize_box(\MPpos{\stepidentifier}) ;
+ cells[b][\cellcounter] := \MPcellsgraphic ;
+ \stopMPdrawing
+ \egroup
+ \fi
+ \global\setbox\stepboxone\hbox
+ {\ifdim\wd\stepboxone>\zeropoint
+ \box\stepboxone\hskip\@@STPChoffset\else
+ \fi\box0}%
+ \global\setbox\stepboxtwo\hbox
+ {\ifdim\wd\stepboxtwo>\zeropoint
+ \box\stepboxtwo\hskip\@@STPChoffset\else
+ \fi\box2}%
+ % flush saved texts
+ \doSTEPchartcellsBA}
+
+\def\doSTEPchartcellsB[#1]#2#3%
+ {\doSTEPchartcellsAB[#1]{#2}{#3}%
+ \doSTEPchartcellsBA}
+
+\def\doSTEPchartcellsAB[#1]#2#3%
+ {\doloop
+ {\ifnum\cellcounter>\textcounter
+ \texts{}{}\else\exitloop
+ \fi}%
+ \doglobal\increment\cellcounter}
+
+\def\doSTEPchartcellsBA
+ {\scratchtoks\stepchartbuffer
+ \stepchartbuffer\emptytoks
+ \the\scratchtoks}
+
+\def\MPcellsgraphic
+ {image ( drawshape (
+ \@@STECalternative, pxy enlarged (-.5*\@@STECoffset),
+ \@@STECrulethickness, \MPcolor{\@@STECframecolor},
+ \MPcolor{\@@STECbackgroundcolor} ) )}
+
+%D Although each step can have only one associated text, the
+%D place where the text is defined determines the starting
+%D point of the connecting arrow. Although several methods are
+%D possible, we've chosen a funny collector that flushes one
+%D step text at a time.
+
+\newtoks\stepchartbuffer
+
+\def\doSTEPcharttextsA[#1]% #2 #3
+ {\dodoSTEPcharttextsA{\cellcounter}{#1}}
+
+\def\dodoSTEPcharttextsA#1#2#3#4% #1=number #2=setup
+ {\dodoSTEPcharttextsAB{#1}{#2}{#3}{#4}\dodoSTEPcharttextsA
+ \ifnum\textcounter>\cellcounter\relax
+ \doglobal\decrement\textcounter\relax
+ \else
+ \setbox0\hbox{\doifsomething{#3}{\@@steptext{#3}}}%
+ \setbox2\hbox{\doifsomething{#4}{\@@steptext{#4}}}%
+ \ifdim\wd0>\zeropoint \!!doneafalse \else \!!doneatrue \fi
+ \ifdim\wd2>\zeropoint \!!donebfalse \else \!!donebtrue \fi
+ \if!!donea
+ \setbox0\hbox to \@@STPChoffset{\hss}%
+ \startMPdrawing
+ texts[t][#1][\textcounter] := nullpicture ;
+ \stopMPdrawing
+ \else
+ \global\chardef\sometextboxone\zerocount
+ \edef\stepidentifier{\stepchartprefix#1-\textcounter-t-t}%
+ \setbox0\hbox to \@@STPChoffset
+ {\hss\hpos{\stepidentifier}{\box0}\hss}%
+ \bgroup
+ \setupSTEPtexts[#2]\initializeSTET
+ \startMPdrawing
+ initialize_box(\MPpos{\stepidentifier}) ;
+ texts[t][#1][\textcounter] := \MPtextsgraphic ;
+ \stopMPdrawing
+ \egroup
+ \fi
+ \if!!doneb
+ \setbox2\hbox to \@@STPChoffset{\hss}%
+ \startMPdrawing
+ texts[b][#1][\textcounter] := nullpicture ;
+ \stopMPdrawing
+ \else
+ \global\chardef\sometextboxtwo\zerocount
+ \edef\stepidentifier{\stepchartprefix#1-\textcounter-b-t}%
+ \setbox2\hbox to \@@STPChoffset
+ {\hss\hpos{\stepidentifier}{\box2}\hss}%
+ \bgroup
+ \setupSTEPtexts[#2]\initializeSTET
+ \startMPdrawing
+ initialize_box(\MPpos{\stepidentifier}) ;
+ texts[b][#1][\textcounter] := \MPtextsgraphic ;
+ \stopMPdrawing
+ \egroup
+ \fi
+ \global\setbox\textboxone\hbox
+ {\hbox to \wd\stepboxone{\box\textboxone\hss}\box0}
+ \global\setbox\textboxtwo\hbox
+ {\hbox to \wd\stepboxtwo{\box\textboxtwo\hss}\box2}
+ \fi}
+
+\def\doSTEPcharttextsB[#1]% #2 #3
+ {\dodoSTEPcharttextsB{\cellcounter}{#1}}
+
+\def\dodoSTEPcharttextsB#1#2#3#4% #1=number #2=setup
+ {\dodoSTEPcharttextsAB{#1}{#2}{#3}{#4}\dodoSTEPcharttextsB
+ \ifnum\textcounter>\cellcounter\relax
+ \doglobal\decrement\textcounter\relax
+ \else
+ \bgroup
+ \initializeSTEL
+ \startMPdrawing
+ lines[t][#1][\textcounter] := \MPcharttoplinesgraphic{#1}\textcounter ;
+ lines[b][#1][\textcounter] := \MPchartbotlinesgraphic{#1}\textcounter ;
+ \stopMPdrawing
+ \egroup
+ \fi}
+
+\def\dodoSTEPcharttextsAB#1#2#3#4#5% #1=number #2=setup
+ {\doglobal\increment\textcounter\relax
+ \ifnum\textcounter>\cellcounter\relax
+ \@EA\appendtoks\@EA#5\@EA{#1}{#2}{#3}{#4}\to\stepchartbuffer
+ \fi}
+
+\def\MPtextsgraphic
+ {image(drawshape(
+ \@@STETalternative, pxy enlarged (-.5*\@@STEToffset),
+ \@@STETrulethickness, \MPcolor{\@@STETframecolor},
+ \MPcolor{\@@STETbackgroundcolor} ) )}
+
+\def\MPcharttoplinesgraphic#1#2%
+ {image(drawline(
+ \@@STELalternative, get_step_chart_top_line(#1,#2),
+ \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )}
+
+\def\MPchartbotlinesgraphic#1#2%
+ {image(drawline(
+ \@@STELalternative, get_step_chart_bot_line(#1,#2),
+ \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )}
+
+%D Step tables are the vertical counterpart of stepcharts.
+
+\newcounter\currentsteptable
+
+\def\steptableprefix{@st@-\currentsteptable-}
+
+\def\startSTEPtable
+ {\dosingleempty\dostartSTEPtable}
+
+\def\dostartSTEPtable[#1]#2\stopSTEPtable
+ {\dostartSTEPaligntable[0][#1]#2\stopSTEPaligntable}
+
+\def\startSTEPaligntable
+ {\dodoubleempty\dostartSTEPaligntable[1]}
+
+\def\dostartSTEPaligntable[#1][#2]#3\stopSTEPaligntable % flag settings data
+ {\ifinsidefloat
+ \else
+ \whitespace
+ \@@STPTbefore
+ \startbaselinecorrection
+ \setlocalhsize
+ \noindent
+ \fi
+ \vbox\bgroup
+ \setupSTEPtables[#2]%
+ \forgetall
+ \pushMPdrawing
+ \doglobal\increment\currentsteptable
+ \startMPdrawing
+ input mp-step.mpii ;
+ begin_step_table ;
+ \stopMPdrawing
+ \initializeSTEP
+ \initializeSTPT
+ \def\startlines{\bgroup\setupSTEPlines}%
+ \def\stoplines {\egroup}%
+ \def\prep##1{\ignorespaces##1\unskip\enspace\ignorespaces}%
+ \def\cell {\dosingleempty\docell}%
+ \def\cells {\dosingleempty\docells}%
+ \def\text {\dosingleempty\dotext}%
+ % first graphic pass, also trial pass
+ \global\dimen1\zeropoint
+ \global\dimen3\zeropoint
+ \global\dimen5\zeropoint
+ \def\docell[##1]%
+ {\docells[##1]{}{}}%
+ \def\docells[##1]##2##3##4%
+ {\doglobal\increment\cellcounter
+ \bgroup
+ \iffirstargument\setupSTEPcells[##1]\fi
+ \initializeSTEC
+ \startMPdrawing
+ if box_found(\MPpos{\steptableprefix\cellcounter-c}) :
+ initialize_box(\MPpos{\steptableprefix\cellcounter-c}) ;
+ cells[\cellcounter] := \MPcellsgraphic ;
+ fi ;
+ \stopMPdrawing
+ \egroup
+ \def\do####1####2%
+ {\setbox\scratchbox\hbox{\@@stepfake{####2}}%
+ \ifdim\wd\scratchbox>\dimen####1\global\dimen####1=\wd\scratchbox\fi}%
+ \ifcase#1\else\do1{##2}\do3{##3}\fi\do5{##4}}%
+ \def\dotext[##1]##2%
+ {\bgroup
+ \iffirstargument\setupSTEPtexts[##1]\fi
+ \initializeSTET
+ \startMPdrawing
+ if box_found(\MPpos{\steptableprefix\cellcounter-t}) :
+ initialize_box(\MPpos{\steptableprefix\cellcounter-t}) ;
+ texts[\cellcounter] := \MPtextsgraphic ;
+ fi ;
+ \stopMPdrawing
+ \egroup}
+ \doglobal\newcounter\cellcounter#3
+ % second graphic pass pass, drawing lines
+ \def\docells[##1]##2##3##4%
+ {\doglobal\increment\cellcounter}
+ \def\dotext[##1]##2%
+ {\bgroup
+ \initializeSTEL
+ \startMPdrawing
+ lines[\cellcounter] := \MPtablelinesgraphic ;
+ \stopMPdrawing
+ \egroup}
+ \doglobal\newcounter\cellcounter#3
+ % finishing graphic touch
+ \startMPdrawing
+ nofcells := \cellcounter ;
+ end_step_table ;
+ anchor_box(\MPpos{\steptableprefix origin}) ;
+ \stopMPdrawing
+ \MPdrawingdonetrue
+ \doifelse\@@STPTmethod{0}
+ {\setbox0\null}
+ {\setbox0\vbox{\MPstaticgraphictrue\getMPdrawing}}%
+ \resetMPdrawing
+ % typesetting pass
+ \dimen6=\@@STPTdistance \dimen6=2\dimen6
+ % cell width
+ \dimen8=\dimen1
+ \advance\dimen8\dimen3
+ \advance\dimen8\dimen5
+ % offset width
+ \ifcase#1\else \advance\dimen8 \dimen6 \fi
+ % arrow width
+ \advance\dimen8 \@@STPTwidth
+ \advance\dimen8 \@@STPToffset
+ \advance\dimen8 \@@STPToffset
+ \def\docells[##1]##2##3##4%
+ {\doglobal\increment\cellcounter
+ \def\do####1####2####3####4% % strut really needed there !
+ {\hbox to \dimen####1{####2\@@stepfake{####3}\strut####4}}%
+ \setbox8\hbox
+ {\ifcase#1\else
+ \do1\hss{##2}\relax \hskip\@@STPTdistance
+ \do3\hss{##3}\hss \hskip\@@STPTdistance
+ \fi
+ \do5\relax{##4}\hss}%
+ \hpos{\steptableprefix\cellcounter-c}{\@@stepcell{\box8}}
+ \endgraf
+ \nointerlineskip
+ \kern\@@STPTvoffset}
+ \def\dotext[##1]##2%
+ {\bgroup
+ \hskip\dimen8
+ \advance\hsize-\dimen8
+ \advance\hsize-\dimen6 % twice the offset
+ \setbox0\hbox{\@@steptext{##2}}%
+% to do
+% \ifdim\wd0>\hsize
+% \setbox0=\vbox{\@@steptext{##2}}%
+% \fi
+% align
+ \hpos{\steptableprefix\cellcounter-t}{\box0}%
+ \endgraf
+ \egroup
+ \nointerlineskip
+ \kern\@@STPTvoffset}
+ \setbox2\vbox
+ {\doglobal\newcounter\cellcounter
+ #3\kern-\@@STPTvoffset}
+ \hbox
+ {\scratchdimen\wd0
+ \advance\scratchdimen \MPllx bp
+ \raise\MPlly bp\box0
+ \hskip-\scratchdimen
+ \hpos{\steptableprefix origin}{\box2}}
+ \popMPdrawing
+ \egroup
+ \ifinsidefloat \else \stopbaselinecorrection \@@STPTafter \fi}
+
+\def\MPtablelinesgraphic
+ {image ( drawline (
+ \@@STELalternative, get_step_table_line(\cellcounter),
+ \@@STELrulethickness, \MPcolor{\@@STELcolor} ) )}
+
+\protect
+
+\continueifinputfile{m-steps.tex}
+
+% A simple paragraph-flow test:
+
+\starttext
+
+\startbuffer
+\startSTEPchart
+\cells {A} {B}
+\cells {one} {five} \texts{$+2$}{$-2$}
+\cells {two} {four} \texts{$+3$}{$-3$}
+\cells {three} {three} \texts{$+4$}{$-4$}
+\cells {four} {two} \texts{$+5$}{$-5$}
+\cells {five} {one}
+\stopSTEPchart
+\stopbuffer
+
+\getbuffer
+
+\startnarrower \getbuffer \stopnarrower
+
+\placefigure[left]{}{\getbuffer}
+
+\stoptext
diff --git a/tex/context/modules/mkii/m-subsub.mkii b/tex/context/modules/mkii/m-subsub.mkii
new file mode 100644
index 000000000..88be11680
--- /dev/null
+++ b/tex/context/modules/mkii/m-subsub.mkii
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=m-subsub,
+%D version=2000.12.14,
+%D title=\CONTEXT\ Private Modules,
+%D subtitle=More Section Levels,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. This module is not public.
+
+\unprotect
+
+\definesection[\s!section-8]
+\definesection[\s!section-9]
+\definesection[\s!section-10]
+\definesection[\s!section-11]
+\definesection[\s!section-12]
+
+\definehead
+ [\v!subsubsubsubsubsection]
+ [\c!section=\s!section-8,
+ \c!default=\v!subsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsection]
+ [\c!section=\s!section-9,
+ \c!default=\v!subsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsection]
+ [\c!section=\s!section-10,
+ \c!default=\v!subsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsection]
+ [\c!section=\s!section-11,
+ \c!default=\v!subsubsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubsection]
+ [\c!section=\s!section-12,
+ \c!default=\v!subsubsubsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-tex4ht.mkii b/tex/context/modules/mkii/m-tex4ht.mkii
new file mode 100644
index 000000000..8a3dc9dbb
--- /dev/null
+++ b/tex/context/modules/mkii/m-tex4ht.mkii
@@ -0,0 +1,9 @@
+%D Preliminaty module
+
+\input tex4ht.sty
+
+\appendtoks
+ \Preamble{\env{ht-1},\env{ht-2},html}\EndPreamble
+\to \everystarttext
+
+\endinput \ No newline at end of file
diff --git a/tex/context/modules/mkii/m-units.mkii b/tex/context/modules/mkii/m-units.mkii
new file mode 100644
index 000000000..af4629d48
--- /dev/null
+++ b/tex/context/modules/mkii/m-units.mkii
@@ -0,0 +1,904 @@
+%D \module
+%D [ file=m-units,
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Scientific Units,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Scientific units can be typeset in math mode pretty well,
+%D but occasionally one has to take care of spacing.
+%D Furthermore, entering these units is not that natural as
+%D wanted. Therefore this module presents a more natural way of
+%D doing things, like:
+%D
+%D \starttyping
+%D 1.23 \Cubic \Meter \Per \Second
+%D \stoptyping
+%D
+%D This example shows that we use the order in which we say
+%D things, instead of typeset things. There is a separate
+%D manual for this module.
+
+%D Message number~1 deals with overruling the \type {\Degrees}
+%D macro defined in the core modules. Let's say that this is
+%D an upward compatibility issue.
+
+\startmessages dutch library: units
+ title: eenheden
+ 1: gebruik \string\Degrees\space\string\Celsius\space in plaats van \string\Celsius !
+\stopmessages
+
+\startmessages english library: units
+ title: units
+ 1: use \string\Degrees\space\string\Celsius\space instead of \string\Celsius !
+\stopmessages
+
+\startmessages german library: units
+ title: Einheiten
+ 1: Verwende \string\Degrees\space\string\Celsius\space statt \string\Celsius !
+\stopmessages
+
+\startmessages italian library: units
+ title: unita
+ 1: usare \string\Degrees\space\string\Celsius\space invece di \string\Celsius !
+\stopmessages
+
+\startmessages norwegian library: units
+ title: enheter
+ 1: bruk \string\Degrees\space\string\Celsius\space istedenfor \string\Celsius !
+\stopmessages
+
+\startmessages romanian library: units
+ title: unitati
+ 1: folositi \string\Degrees\space\string\Celsius\space in locul \string\Celsius !
+\stopmessages
+
+\startmessages french library: units
+ title: unitas
+ 1: utilisez \string\Degrees\space\string\Celsius\space A la place de \string\Celsius !
+\stopmessages
+
+\unprotect
+
+%D This runtime loadable module implements a way of defining
+%D units. The core macro is \type {\dimension}, a rather clever
+%D one that is able to cooperate with some other dimension
+%D related macros. As said, this module enables user to enter:
+%D
+%D \startbuffer
+%D some 10 \Square \Meter \Per \Second or more
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D as:
+%D
+%D \typebuffer
+%D
+%D The units itself are implemented as synonyms.
+%D
+%D \starttyping
+%D \definesynonyms [unit] [units] [\unitmeaning]
+%D \setupsynonyms [unit] [textstyle=\dimension]
+%D \stoptyping
+%D
+%D This definition means that we can ask for the meaning of a
+%D unit using \type {\unitmeaning} and get a list of used
+%D units by saying \type {\placelistofunits}
+%D
+%D We have to use the command \type {\unitmeaning} instead
+%D of \type {\meaning}, simply because the latter is a \TEX\
+%D primitive we don't want to loose. We use the label text
+%D mechanism for translations.
+
+%D \macros
+%D {dimension}
+%D
+%D The core of this module is the low level macro \type
+%D {\dimension}. Before presenting this macro, it's best to
+%D look at some applications, because it's supposed to show
+%D some intelligence that can beter be understood from the
+%D context.
+%D
+%D The next useless examples show some of the cases we want
+%D to handle in a proper way.
+%D
+%D \startbuffer
+%D ... 10 \Square \Meter \Per \Volt \
+%D ... 10 \Square \Meter \Volt \
+%D ... 10 \Meter \Volt \
+%D ... 10 \Milli \Square \Meter \Per \Volt \
+%D ... 10 \Square \Milli \Meter \Per \Volt \
+%D ... 10 \Meter \Times \Meter \
+%D ... 10 \Square \Meter \Times \Meter \
+%D ... 10 \Square \Milli \Meter \Times \Meter \
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D Becomes:
+%D
+%D \getbuffer
+
+%D \macros
+%D {mathematicstypeface, dimensiontypeface,
+%D dimensionhalfspace, dimensionbackspace}
+%D
+%D There are some low level constants, that can be changed
+%D when needed. Some day I will write a decent setup command.
+
+\def\mathematicstypeface{\rm}
+\def\dimensiontypeface {\tf}
+
+\def\dimensionhalfspace {\ifmmode\,\else\hskip+.1em\relax\fi}
+\def\dimensionbackspace {\ifmmode\!\else\hskip-.1em\relax\fi}
+
+%D \macros
+%D {smashdimensionpower}
+%D
+%D Sometimes the baseline distance is not enough to provide
+%D for superscripts, so we smash their height by default.
+
+\newif\ifsmashdimensionpower \smashdimensionpowertrue
+
+%D The dimension mechanism uses a lot of signals to keep
+%D track if the current state.
+
+\newsignal\dimensionsignal
+\newsignal\dimensionpowersignal
+\newsignal\dimensionmidfixsignal
+\newsignal\dimensionaddfixsignal
+
+\let\thedimensionprefix = \empty
+\let\thedimensionpower = \empty
+
+%D \macros
+%D {spaceddimensions,textdimensions}
+%D
+%D The actual definition of \type {\dimension} overruled the
+%D one in the core modules. The boolean can be used to
+%D force spacing between units. Vergelijk {\Newton \Meter}
+%D eens met {\spaceddimensionstrue \Newton \Meter}. The
+%D rather ugly test prevents problems with nested dimensions.
+
+\newif\ifspaceddimensions \spaceddimensionsfalse % user switch
+\newif\iftextdimensions \textdimensionsfalse % user switch
+
+%D You can see the consequence of forcing text dimensions
+%D when you compare the following code:
+%D
+%D \starttyping
+%D {\rm test \Square \Meter \Per \Second\ ziezo\Degrees} \par
+%D {\ss test \Square \Meter \Per \Second\ ziezo} \par
+%D {\tt test \Square \Meter \Per \Second\ ziezo}
+%D
+%D \textdimensionstrue
+%D
+%D {\rm test \Square \Meter \Per \Second\ ziezo} \par
+%D {\ss test \Square \Meter \Per \Second\ ziezo} \par
+%D {\tt test \Square \Meter \Per \Second\ ziezo}
+%D \stoptyping
+
+\newif\ifnesteddimension \nesteddimensionfalse % local switch
+
+\def\dodimensionpower#1%
+ {\iftextdimensions\expandafter\high\else\expandafter^\fi{#1}}
+
+\def\ustartmathmode {\iftextdimensions\else\expandafter\startmathmode \fi}
+\def\ustopmathmode {\iftextdimensions\else\expandafter\stopmathmode \fi}
+\def\umathematicstypeface{\iftextdimensions\else\expandafter\mathematicstypeface\fi}
+
+%D In forced text mode, we ignore spacing in monospaced fonts.
+
+\def\udimensionhalfspace {\dodimensionspace\dimensionhalfspace}
+\def\udimensionbackspace {\dodimensionspace\dimensionbackspace}
+
+\def\dodimensionspace
+ {\iftextdimensions
+ \begingroup
+ \setbox0\hbox{i}%
+ \setbox2\hbox{m}%
+ \ifdim\wd0=\wd2
+ \endgroup
+ \@EAEAEA\gobbleoneargument
+ \else
+ \endgroup
+ \fi
+ \fi}
+
+\unexpanded\def\dimension#1%
+ {\begingroup
+ \global\let\savedthedimensionprefix\thedimensionprefix
+ \global\let\savedthedimensionpower\thedimensionpower
+ \unexpanded\def\dimension##1{\global\nesteddimensiontrue}%
+ \let\dimensionprefix\dimension
+ \let\dimensionmidfix\dimension
+ \let\dimensionsuffix\dimension
+ \let\dimensionpower \dimension
+ \global\nesteddimensionfalse
+ \setbox\scratchbox\hbox{\ustartmathmode#1\ustopmathmode}% pre-roll
+ \global\let\thedimensionprefix\savedthedimensionprefix
+ \global\let\thedimensionpower \savedthedimensionpower
+ \endgroup
+ \ifnesteddimension#1\else\dodimension{#1}\fi}
+
+\def\dodimension#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\zeropoint\relax
+ \ifmmode
+ \udimensionhalfspace
+ \udimensionhalfspace
+ \fi
+ \ustartmathmode\dimensiontypeface
+ \else
+ \ustartmathmode\dimensiontypeface
+ \ifspaceddimensions
+ \ifdim\scratchdimen=\dimensionsignal\relax
+ \udimensionhalfspace
+ \else\ifdim\scratchdimen=\dimensionpowersignal\relax
+ \udimensionhalfspace
+ \fi
+ \fi
+ \fi
+ \fi
+ \umathematicstypeface\thedimensionprefix#1%
+ \ifx\thedimensionpower\empty
+ \else\ifsmashdimensionpower
+ \setbox\scratchbox=\hbox
+ {\iftextdimensions
+ \tx\thedimensionpower
+ \else
+ $\scriptstyle\thedimensionpower$%
+ \fi}%
+ \ht\scratchbox=\zeropoint
+ \dodimensionpower{\box\scratchbox}%
+ \else
+ \dodimensionpower{\thedimensionpower}%
+ \fi\fi
+ \ustopmathmode
+ % otherwise nobreak before space in 2 \Milli \Meter\ blabla
+ \doifnotmode{atpragma}{\nobreak}% this was always \nobreak
+ % only test this at pragma
+ \ifx\thedimensionpower\empty
+ \hskip\dimensionsignal
+ \else
+ \hskip\dimensionpowersignal
+ \fi
+ \global\let\thedimensionprefix\empty
+ \global\let\thedimensionpower\empty}
+
+%D \macros
+%D {dontbreakdimension,
+%D dimensionprefix, dimensionaddfix,
+%D dimensionnopfix, dimensionmidfix,
+%D dimensionpower}
+%D
+%D Here are some auxilliary macros.
+
+\def\dontbreakdimension
+ {\scratchdimen\lastskip
+ \unskip
+ \nobreak
+ \hskip\scratchdimen
+ \nobreak}
+
+\def\dimensionprefix#1%
+ {\gdef\thedimensionprefix{#1}}
+
+\def\dimensionaddfix#1%
+ {\unskip
+ %\mathematics{\umathematicstypeface#1}%
+ \ustartmathmode\umathematicstypeface#1\ustopmathmode
+ \nobreak
+ \hskip\dimensionaddfixsignal}
+
+\def\dimensionnopfix#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\dimensionpowersignal\relax
+ \ustartmathmode
+ \else
+ \ustartmathmode
+ \udimensionhalfspace
+ \nobreak
+ \fi
+ \umathematicstypeface#1%
+ \ustopmathmode
+ \nobreak
+ \hskip\dimensionsignal}
+
+\def\dimensionmidfix#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\dimensionpowersignal\relax
+ \ustartmathmode
+ \udimensionbackspace
+ \nobreak
+ \else
+ \ustartmathmode
+ \fi
+ \umathematicstypeface#1%
+ \ustopmathmode
+ \nobreak
+ \hskip\dimensionmidfixsignal}
+
+\def\dimensionpower#1%
+ {\gdef\thedimensionpower{#1}}
+
+%D \macros
+%D {SIunits, noSI, doSI}
+%D
+%D Some low level unit switching macros:
+
+\newif\ifSIunits \SIunitstrue
+
+\def\noSI#1{\begingroup\SIunitsfalse#1\endgroup}
+\def\doSI#1{\begingroup\SIunitstrue #1\endgroup}
+
+%D \macros
+%D {Degrees}
+%D
+%D We can fake the degrees symbol with:
+
+\def\Degrees{\dimensionaddfix{\mathematics{^\circ}}}
+
+%D \macros
+%D {Unit, NoUnit}
+%D
+%D When a dimension has no leading number, we can use \type
+%D {\Unit}, and when no unit is appended, \type {\NoUnit} is
+%D to be used, just to prevent the prefix migrating to the
+%D next occasion.
+
+\def\Unit {\hskip\dimensionsignal}
+\def\NoUnit {\dimension{}}
+
+%D The mechanism described at the top of this module, depends
+%D on several dimensional components, like prefixes:
+
+\def\Atto {\dimensionprefix{a}}
+\def\Femto {\dimensionprefix{f}}
+\def\Pico {\dimensionprefix{p}}
+\def\Nano {\dimensionprefix{n}}
+\def\Micro {\dimensionprefix{\iftextdimensions u\else\mu\fi}}
+\def\Milli {\dimensionprefix{m}}
+\def\Centi {\dimensionprefix{c}}
+\def\Deci {\dimensionprefix{d}} % 10^01
+\def\Hecto {\dimensionprefix{h}} % 10^02
+\def\Kilo {\dimensionprefix{k}} % 10^03
+\def\Mega {\dimensionprefix{M}} % 10^06
+\def\Giga {\dimensionprefix{G}} % 10^09
+\def\Tera {\dimensionprefix{T}} % 10^12
+\def\Peta {\dimensionprefix{P}} % 10^15
+\def\Exa {\dimensionprefix{E}} % 10^18
+
+%def\Terra {\dimensionprefix{T}} % for old times sake
+
+\def\Kibi {\dimensionprefix{ki}} % 2^10
+\def\Mebi {\dimensionprefix{Mi}} % 2^20
+\def\Gibi {\dimensionprefix{Gi}} % 2^30
+\def\Tebi {\dimensionprefix{Ti}} % 2^40
+\def\Pebi {\dimensionprefix{Pi}} % 2^50
+
+%D and binary prefixes:
+
+\def\Kibi {\dimensionprefix{Ki}}
+\def\Mebi {\dimensionprefix{Mi}}
+\def\Gibi {\dimensionprefix{Gi}}
+\def\Tebi {\dimensionprefix{Ti}}
+\def\Pebi {\dimensionprefix{Pi}}
+\def\Exbi {\dimensionprefix{Ei}}
+\def\Zebi {\dimensionprefix{Zi}}
+\def\Yobi {\dimensionprefix{Yi}}
+
+%D and operators:
+
+\def\Times {\dimensionnopfix{\iftextdimensions.\else\cdot\fi}}
+\def\Solidus {\dimensionmidfix{/}}
+\def\Per {\dimensionmidfix{/}}
+\def\OutOf {\dimensionnopfix{:}}
+
+%D and suffixes:
+
+\def\Linear {\dimensionpower{1}}
+\def\Square {\dimensionpower{2}}
+\def\Cubic {\dimensionpower{3}}
+
+\def\Inverse {\dimensionpower{-1}}
+\def\ILinear {\dimensionpower{-1}}
+\def\ISquare {\dimensionpower{-2}}
+\def\ICubic {\dimensionpower{-3}}
+
+%D Apart from these components, the units themselves are
+%D defined using the synonym mechanism. First we define some
+%D length and volume related units.
+
+\getvalue{\v!unit} [Meter] {m} {meter}
+\getvalue{\v!unit} [pMeter] {\Pico \Meter} {picometer}
+\getvalue{\v!unit} [nMeter] {\Nano \Meter} {nanometer}
+\getvalue{\v!unit} [uMeter] {\Micro \Meter} {micrometer}
+\getvalue{\v!unit} [mMeter] {\Milli \Meter} {millimeter}
+\getvalue{\v!unit} [cMeter] {\Centi \Meter} {centimeter}
+\getvalue{\v!unit} [dMeter] {\Deci \Meter} {decimeter}
+\getvalue{\v!unit} [hMeter] {\Hecto \Meter} {hectometer}
+\getvalue{\v!unit} [kMeter] {\Kilo \Meter} {kilometer}
+
+%D After some discussion on the \CONTEXT\ mailing list in
+%D february 2002 it was decided to go from L to l for liters
+%D (Karel Wesselings alternative: \mathematics{\ell}).
+
+\getvalue{\v!unit} [Liter] {l} {liter}
+\getvalue{\v!unit} [mLiter] {\Milli \Liter} {milliliter}
+\getvalue{\v!unit} [cLiter] {\Centi \Liter} {centiliter}
+\getvalue{\v!unit} [dLiter] {\Deci \Liter} {deciliter}
+
+%D Next we define time related units (\type {\ifSI} still dutch only).
+
+\getvalue{\v!unit} [Sec] {s} {\labeltext{u:sec}}
+\getvalue{\v!unit} [fSec] {\Femto \Sec} {\labeltext{u:fsec}}
+\getvalue{\v!unit} [pSec] {\Pico \Sec} {\labeltext{u:psec}}
+\getvalue{\v!unit} [nSec] {\Nano \Sec} {\labeltext{u:nsec}}
+\getvalue{\v!unit} [uSec] {\Micro \Sec} {\labeltext{u:usec}}
+\getvalue{\v!unit} [mSec] {\Milli \Sec} {\labeltext{u:msec}}
+\getvalue{\v!unit} [Year] {\ifSIunits a \else j\fi} {\labeltext{u:year}}
+\getvalue{\v!unit} [Month] {m} {\labeltext{u:month}}
+\getvalue{\v!unit} [Week] {w} {\labeltext{u:week}}
+\getvalue{\v!unit} [Day] {d} {\labeltext{u:day}}
+\getvalue{\v!unit} [Hour] {\ifSIunits h \else u\fi} {\labeltext{u:hour}}
+\getvalue{\v!unit} [Min] {min} {\labeltext{u:min}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:sec=seconde,
+ u:psec=picoseconde,
+ u:fsec=femtoseconde,
+ u:nsec=nanoseconde,
+ u:usec=microseconde,
+ u:msec=milliseconde,
+ u:year=jaar,
+ u:month=maand,
+ u:week=week,
+ u:day=dag,
+ u:hour=uur,
+ u:min=minuten]
+
+\setuplabeltext
+ [\s!en]
+ [u:sec=second,
+ u:fsec=femtosecond,
+ u:psec=picosecond,
+ u:nsec=nanosecond,
+ u:usec=microsecond,
+ u:msec=millisecond,
+ u:year=year,
+ u:month=month,
+ u:week=week,
+ u:day=day,
+ u:hour=hour,
+ u:min=minutes]
+
+\setuplabeltext
+ [\s!de]
+ [u:sec=Sekunde,
+ u:fsec=Femtosekunde,
+ u:psec=Picosekunde,
+ u:nsec=Nanosekunde,
+ u:usec=Microsekunde,
+ u:msec=Millisekunde,
+ u:year=Jahr,
+ u:month=Monat,
+ u:week=Woche,
+ u:day=Tag,
+ u:hour=Stunde,
+ u:min=Minuten]
+
+\setuplabeltext
+ [\s!hr]
+ [u:sec=sekunda,
+ u:fsec=femtosekunda,
+ u:psec=pikosekunda,
+ u:nsec=nanosekunda,
+ u:usec=mikrosekunda,
+ u:msec=milisekunda,
+ u:year=godina,
+ u:month=mjesec,
+ u:week=tjedan,
+ u:day=dan,
+ u:hour=sat,
+ u:min=minuta]
+
+\setuplabeltext
+ [\s!it]
+ [u:sec=secondo,
+ u:fsec=femtosecondo,
+ u:psec=picosecondo,
+ u:nsec=nanosecondo,
+ u:usec=microsecondo,
+ u:msec=millisecondo,
+ u:year=anno,
+ u:month=mese,
+ u:week=settimana,
+ u:day=giorno,
+ u:hour=ora,
+ u:min=minuti]
+
+%D Then we define some angles.
+
+\getvalue{\v!unit} [Rad] {rad} {\labeltext{u:rad}}
+\getvalue{\v!unit} [Deg] {{\mathematics{^\circ}}} {\labeltext{u:deg}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:rad=hoek radialen,
+ u:deg=hoek graden]
+
+\setuplabeltext
+ [\s!en]
+ [u:rad=angle radians,
+ u:deg=angle degrees]
+
+\setuplabeltext
+ [\s!de]
+ [u:rad=Bogenma\SS,
+ u:deg=Gradma\SS]
+
+\setuplabeltext
+ [\s!hr]
+ [u:rad=radijani,
+ u:deg=kutni stupnjevi]
+
+\setuplabeltext
+ [\s!it]
+ [u:rad=radianti,
+ u:deg=angoli sessagesimali]
+
+%D Rotation and frequency related units are defined by:
+
+\getvalue{\v!unit} [Hertz] {Hz} {Hertz}
+\getvalue{\v!unit} [kHertz] {\Kilo \Hertz} {kilo Hertz}
+\getvalue{\v!unit} [MHertz] {\Mega \Hertz} {mega Hertz}
+\getvalue{\v!unit} [GHertz] {\Giga \Hertz} {giga Hertz}
+\getvalue{\v!unit} [THertz] {\Tera \Hertz} {tera Hertz}
+\getvalue{\v!unit} [mHertz] {\Milli \Hertz} {milli Hertz}
+
+\getvalue{\v!unit} [RevPerSec] {RPS} {\labeltext{u:rps}}
+\getvalue{\v!unit} [RevPerMin] {RPM} {\labeltext{u:rpm}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:rps=omwentelingen per seconde,
+ u:rpm=omwentelingen per minuut]
+
+\setuplabeltext
+ [\s!en]
+ [u:rps=revolutions per second,
+ u:rpm=revolutions per minute]
+
+\setuplabeltext
+ [\s!de]
+ [u:rps=Umdrehungen pro Sekunde,
+ u:rpm=Umdrehungen pro Minute]
+
+\setuplabeltext
+ [\s!hr]
+ [u:rps=okretaji po sekundi,
+ u:rpm=okretaji po minuti]
+
+\setuplabeltext
+ [\s!it]
+ [u:rps=giri al secondo,
+ u:rpm=giri al minuto]
+
+%D Mass and force:
+
+\getvalue{\v!unit} [Gram] {g} {gram}
+\getvalue{\v!unit} [uGram] {\Micro \Gram} {microgram}
+\getvalue{\v!unit} [mGram] {\Milli \Gram} {milligram}
+\getvalue{\v!unit} [kGram] {\Kilo \Gram} {kilogram}
+\getvalue{\v!unit} [Atom] {u} {\labeltext{u:u}}
+
+\getvalue{\v!unit} [Newton] {N} {Newton}
+\getvalue{\v!unit} [kNewton] {\Kilo \Newton} {kilo Newton}
+
+\getvalue{\v!unit} [Pascal] {Pa} {Pascal}
+\getvalue{\v!unit} [mPascal] {\Milli \Pascal} {milli Pascal}
+\getvalue{\v!unit} [kPascal] {\Kilo \Pascal} {kilo Pascal}
+
+\setuplabeltext
+ [\s!nl]
+ [u:u=atomaire massa eenheid]
+
+\setuplabeltext
+ [\s!en]
+ [u:u=atom mass unit]
+
+\setuplabeltext
+ [\s!de]
+ [u:u=Atomare Masseneinheit]
+
+\setuplabeltext
+ [\s!hr]
+ [u:u=unificirana atomska jedinica mase]
+
+\setuplabeltext
+ [\s!it]
+ [u:u=unit\`a di massa atomica]
+
+%D Energy units comes in two alternatives:
+
+\getvalue{\v!unit} [Joule] {J} {Joule}
+\getvalue{\v!unit} [mJoule] {\Milli \Joule} {milli Joule}
+\getvalue{\v!unit} [kJoule] {\Kilo \Joule} {kilo Joule}
+\getvalue{\v!unit} [MJoule] {\Mega \Joule} {mega Joule}
+\getvalue{\v!unit} [GJoule] {\Giga \Joule} {giga Joule}
+
+\getvalue{\v!unit} [Watt] {W} {Watt}
+\getvalue{\v!unit} [mWatt] {\Milli \Watt} {milli Watt}
+\getvalue{\v!unit} [kWatt] {\Kilo \Watt} {kilo Watt}
+\getvalue{\v!unit} [MWatt] {\Mega \Watt} {mega Watt}
+\getvalue{\v!unit} [GWatt] {\Giga \Watt} {giga Watt}
+\getvalue{\v!unit} [TWatt] {\Tera \Watt} {tera Watt}
+
+%D Although Celsius is no longer permitted, we define it by
+%D saying:
+
+\getvalue{\v!unit} [Celsius] {C} {Celsius}
+\getvalue{\v!unit} [Kelvin] {K} {Kelvin}
+\getvalue{\v!unit} [Fahrenheit] {F} {Fahrenheit}
+
+%D Some chemic related units are:
+
+\getvalue{\v!unit} [Mol] {mol} {mol}
+\getvalue{\v!unit} [mMol] {\Milli \Mol} {millimol}
+\getvalue{\v!unit} [kMol] {\Kilo \Mol} {kilomol}
+\getvalue{\v!unit} [Molair] {M} {molair (\Mol \Per \Liter)}
+\getvalue{\v!unit} [Equivalent] {eq} {equivalent}
+\getvalue{\v!unit} [mEquivalent] {\Milli \Equivalent} {milli equivalent}
+
+%D There are quite a lot units related to electricity and
+%D magnetism:
+
+\getvalue{\v!unit} [Farad] {F} {Farad}
+\getvalue{\v!unit} [pFarad] {\Pico \Farad} {pico Farad}
+\getvalue{\v!unit} [nFarad] {\Nano \Farad} {nano Farad}
+\getvalue{\v!unit} [uFarad] {\Micro \Farad} {micro Farad}
+\getvalue{\v!unit} [mFarad] {\Milli \Farad} {milli Farad}
+
+\getvalue{\v!unit} [Ohm] {\Omega} {Ohm}
+\getvalue{\v!unit} [kOhm] {\Kilo \Ohm} {kilo Ohm}
+
+\getvalue{\v!unit} [Siemens] {S} {Siemens}
+
+\getvalue{\v!unit} [Ampere] {A} {Amp\`ere}
+\getvalue{\v!unit} [mAmpere] {\Milli \Ampere} {milli Amp\`ere}
+
+\getvalue{\v!unit} [Coulomb] {C} {Coulomb}
+
+\getvalue{\v!unit} [Volt] {V} {Volt}
+\getvalue{\v!unit} [mVolt] {\Milli \Volt} {milli Volt}
+\getvalue{\v!unit} [kVolt] {\Kilo \Volt} {kilo Volt}
+\getvalue{\v!unit} [eVolt] {eV} {electronvolt}
+\getvalue{\v!unit} [keVolt] {\Kilo \eVolt} {kilo electronvolt}
+\getvalue{\v!unit} [MeVolt] {\Mega \eVolt} {mega electronvolt}
+
+\getvalue{\v!unit} [Tesla] {T} {Tesla}
+
+\getvalue{\v!unit} [VoltAC] {V_{\xbox{ac}}} {\labeltext{u:vac}}
+\getvalue{\v!unit} [VoltDC] {V_{\xbox{dc}}} {\labeltext{u:vdc}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:vac=wisselspanning,
+ u:vdc=gelijkspanning]
+
+\setuplabeltext
+ [\s!en]
+ [u:vac=alternating current,
+ u:vdc=direct current]
+
+\setuplabeltext
+ [\s!de]
+ [u:vac=Wechselspannung,
+ u:vdc=Gleichspannung]
+
+\setuplabeltext
+ [\s!hr]
+ [u:vac=izmjeni\ccaron ni napon,
+ u:vdc=istosmjerni napon]
+
+\setuplabeltext
+ [\s!it]
+ [u:vac=corrente alternata,
+ u:vdc=corrente continua]
+
+%D Network bandwidth is specified in Bits:
+
+\getvalue{\v!unit} [Bit] {bit} {\labeltext{u:bit}}
+\getvalue{\v!unit} [Baud] {Bd} {Baud (Bit/s)}
+
+%D Computer memory size is specified in Bytes:
+
+\getvalue{\v!unit} [Byte] {B} {\labeltext{u:byte}}
+\getvalue{\v!unit} [kByte] {\Kilo \Byte} {kilo Byte}
+\getvalue{\v!unit} [MByte] {\Mega \Byte} {mega Byte}
+\getvalue{\v!unit} [GByte] {\Giga \Byte} {giga Byte}
+\getvalue{\v!unit} [TByte] {\Tera \Byte} {tera Byte}
+
+\setuplabeltext
+ [\s!en]
+ [u:bit=Bit,
+ u:byte=Byte]
+
+\setuplabeltext
+ [\s!hr]
+ [u:bit=bit,
+ u:byte=bajt]
+
+%D Telecommunication call density is specified in Erlangs:
+
+\getvalue{\v!unit} [Erlang] {E} {Erlang}
+
+%D Some radiation related units:
+
+\getvalue{\v!unit} [Bequerel] {Bq} {Bequerel}
+\getvalue{\v!unit} [MBequerel] {\Mega \Bequerel} {Bequerel}
+\getvalue{\v!unit} [Sievert] {Sv} {Sievert}
+\getvalue{\v!unit} [mSievert] {\Milli \Sievert} {milli Sievert}
+
+%D Light:
+
+\getvalue{\v!unit} [Candela] {cd} {Candela}
+
+%D and some sound ones:
+
+\getvalue{\v!unit} [Bell] {B} {Bell}
+\getvalue{\v!unit} [dBell] {\Deci \Bell} {decibel}
+
+%D We also define some non||regular, sometimes even forbidden,
+%D units:
+
+\getvalue{\v!unit} [At] {at} {\labeltext{u:at}}
+\getvalue{\v!unit} [Atm] {atm} {\labeltext{u:atm}}
+\getvalue{\v!unit} [Bar] {bar} {bar (100 \Kilo \Pascal)}
+\getvalue{\v!unit} [EVolt] {eV} {electronvolt}
+\getvalue{\v!unit} [Foot] {ft} {\labeltext{u:ft}}
+\getvalue{\v!unit} [Inch] {inch} {\labeltext{u:inch}}
+\getvalue{\v!unit} [Cal] {cal} {\labeltext{u:cal}}
+\getvalue{\v!unit} [Force] {f} {\labeltext{u:f}}
+\getvalue{\v!unit} [kCal] {\Kilo \Cal} {\labeltext{u:kcal}}
+\getvalue{\v!unit} [Lux] {lux} {lux}
+
+
+\def\xPercent {\dimensionaddfix{\percent }}
+\def\xPromille{\dimensionaddfix{\promille}}
+
+\getvalue{\v!unit} [Percent] {\xPercent } {percent}
+\getvalue{\v!unit} [Permille] {\xPromille} {promille}
+\getvalue{\v!unit} [Promille] {\xPromille} {promille}
+
+%D Some more, thanks to Tobias:
+
+\getvalue{\v!unit} [Gray] {Gr} {Gray}
+\getvalue{\v!unit} [Weber] {Wb} {Weber}
+\getvalue{\v!unit} [Henry] {H} {Henry}
+\getvalue{\v!unit} [Sterant] {sr} {Sterant}
+\getvalue{\v!unit} [Angstrom] {\hbox{\Aring}} {\Aring ngstr\"om}
+\getvalue{\v!unit} [Gauss] {G} {Gauss}
+
+\setuplabeltext
+ [\s!nl]
+ [u:at=technische atmosfeer,
+ u:atm=fysische atmosfeer,
+ u:ft=voet,
+ u:cal=calorie,
+ u:f=kracht (force),
+ u:kcal=kilocalorie]
+
+\setuplabeltext
+ [\s!en]
+ [u:at=technical atmospheric pressure,
+ u:atm=physical atmospheric pressure,
+ u:ft=foot,
+ u:inch=inch,
+ u:cal=calory,
+ u:f=force,
+ u:kcal=kilocalory]
+
+\setuplabeltext
+ [\s!de]
+ [u:at=Technischer atmosph\"arischer Druck,
+ u:atm=physkalischer atmosph\"arischer Druck,
+ u:ft=Fu\SS,
+ u:cal=Kalorien,
+ u:f=Force,
+ u:kcal=Kilokalorien]
+
+\setuplabeltext
+ [\s!hr]
+ [u:at=tehni\ccaron ka atmosfera,
+ u:atm=standardna atmosfera,
+ u:ft=stopa,
+ u:inch=in\ccaron a,
+ u:cal=kalorija,
+ u:f=Force,
+ u:kcal=Kilokalorien]
+
+\setuplabeltext
+ [\s!it]
+ [u:at=pressione atmosferica tecnica,
+ u:atm=pressione atmosfera fisica,
+ u:ft=piede,
+ u:cal=caloria,
+ u:f=forza,
+ u:kcal=chilocaloria]
+
+%D Here are some old ones, still there for compatibility
+%D reasons. These will probably be obsolete in a few years.
+
+\def\MeterTwee {\Square \Meter}
+\def\mMeterTwee {\Square \Milli \Meter}
+\def\cMeterTwee {\Square \Centi \Meter}
+\def\dMeterTwee {\Square \Deci \Meter}
+\def\kMeterTwee {\Square \Kilo \Meter}
+
+\def\MeterDrie {\Cubic \Meter}
+\def\mMeterDrie {\Cubic \Milli \Meter}
+\def\cMeterDrie {\Kubic \Centi \Meter}
+\def\dMeterDrie {\Cubic \Deci \Meter}
+\def\kMeterDrie {\Cubic \Kilo \Meter}
+
+\def\LiterTwee {\Square \Liter}
+\def\SecTwee {\Square \Sec}
+\def\SecMinEen {\Inverse \Sec}
+
+%D To make ourselves happy, we define some dutch specific
+%D units:
+
+\startinterface dutch
+
+ \getvalue{\v!unit} [PaardenKracht] {pk} {paardenkracht}
+ \getvalue{\v!unit} [Duits] {D} {duits}
+ \getvalue{\v!unit} [Kwik] {Hg} {kwikkolom}
+ \getvalue{\v!unit} [Hectare] {ha} {hectare}
+ \getvalue{\v!unit} [kGramForce] {\Kilo \Gram \Force} {kilogramforce}
+ \getvalue{\v!unit} [kWattUur] {\Kilo \Watt \Uur} {kilowattuur}
+ \getvalue{\v!unit} [MeterKwik] {\Meter \Kwik} {meter kwikkolom}
+ \getvalue{\v!unit} [Waterkolom] {WK} {waterkolom}
+ \getvalue{\v!unit} [MeterWater] {\Meter \Waterkolom} {meter waterkolom}
+ \getvalue{\v!unit} [DrogeStof] {ds} {droge stof}
+ \getvalue{\v!unit} [Normaal] {N} {normaal}
+
+ \getvalue{\v!unit} [Ton] {t} {ton}
+ \getvalue{\v!unit} [kTon] {\Kilo \Ton} {kiloton}
+
+ \let \OmwPerSec \RevPerSec
+ \let \OmwPerMin \RevPerMin
+ \let \Graden \Deg
+ \let \PaardeKracht \PaardenKracht
+ \let \Atoom \Atom
+ \let \Heure \Hour
+ \let \Jaar \Year
+ \let \Maand \Month
+ \let \Dag \Day
+ \let \Uur \Hour
+
+\stopinterface
+
+%D Finally we define some equivalents. By using \type {\let}
+%D we can be sure that they don't end up double in the lists of
+%D units.
+
+\let \Second \Sec
+\let \Kubic \Cubic
+\let \IKubic \ICubic
+
+%D Option:
+
+% \def\Micro{\dimensionprefix{\iftextdimensions\mathematics\mu \else\mu \fi}}
+% \def\Times{\dimensionnopfix{\iftextdimensions\mathematics\cdot\else\cdot\fi}}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/m-visual.mkii b/tex/context/modules/mkii/m-visual.mkii
new file mode 100644
index 000000000..ae52f6571
--- /dev/null
+++ b/tex/context/modules/mkii/m-visual.mkii
@@ -0,0 +1,315 @@
+%D \module
+%D [ file=m-visual,
+%D version=2000.01.10,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Visualization and Faking,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D This module collect a few more visual debugger features. I
+%D needed them for manuals and styles. The macros are documented
+%D in a my way document.
+
+%D For Mojca:
+%D
+%D \starttyping
+%D \def\simplethesis
+%D {\setupsystem[random=1234]
+%D \title{\fakewords{3}{4}}
+%D \placelist[chapter,section]
+%D \dorecurse{6}
+%D {\chapter{\fakewords{5}{10}}
+%D \dorecurse{5}
+%D {\section{\fakewords{2}{5}}
+%D \dorecurse{2}
+%D {\dorecurse{3}{\fakewords{100}{200}\endgraf}
+%D \placefigure{\fakewords{8}{15}}{\fakefigure{5cm}{3cm}{10cm}{5cm}}
+%D \dorecurse{2}{\fakewords{100}{200}\endgraf}}}}}
+%D
+%D \starttext
+%D \simplethesis
+%D \stoptext
+%D \stoptyping
+
+\definecolor[fakerulecolor] [black]
+\definecolor[fakebaselinecolor] [green]
+\definecolor[fakeparindentcolor][blue]
+
+\newif\iffakebaseline \fakebaselinetrue
+
+\def\fakerule#1%
+ {\strut
+ \startcolor[fakerulecolor]%
+ \iffakebaseline
+ \vrule\!!height1.25ex\!!depth-.05ex\!!width#1%
+ \kern-#1%
+ \vrule\!!height-.05ex\!!depth .25ex\!!width#1%
+ \else
+ \vrule\!!height1.25ex\!!depth .25ex\!!width#1%
+ \fi
+ \stopcolor
+ \allowbreak}
+
+\def\dorandomrecurse#1%
+ {\getrandomcount\scratchcounter{1}{#1}%
+ \dorecurse\scratchcounter}
+
+% can be used in hbox, so %'s are really needed
+
+\unexpanded\def\fakelines#1#2% min max / 3 10
+ {\fakeparindent
+ \scratchdimen\hsize
+ \ifindentation
+ \advance\scratchdimen -\parindent
+ \fi
+ \fakerule\scratchdimen\break
+ \getrandomcount\scratchcounter{\ifcase0#1 3\else#1\fi}{\ifcase0#2 10\else#2\fi}%
+ \dorecurse\scratchcounter{\fakerule\hsize}%
+ \getrandomdimen\scratchdimen{.25\hsize}\hsize
+ \fakerule\scratchdimen
+ \par} % indeed
+
+\unexpanded\def\fakewords
+ {\ifvmode\fakeparindent\fi\onlyfakewords}
+
+\definepalet
+ [fakerule]
+ [fr1c=darkred,
+ fr2c=darkgreen,
+ fr3c=darkblue,
+ fr4c=darkyellow,
+ fr5c=darkgray]
+
+\unexpanded\def\onlyfakewords#1#2% min max / 10 40
+ {\getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}%
+ \dofakewords\scratchcounter
+ } % no \par
+
+\unexpanded\def\fakenwords#1#2% words seed
+ {\fakeparindent
+ \getrandomseed\fakedwordseed
+ \setrandomseed{\ifcase0#2 #1\else#2\fi}%
+ \dofakewords{#1}%
+ \setrandomseed\fakedwordseed
+ } % no \par
+
+\def\dofakewords#1%
+ {\bgroup
+ \dorecurse{#1}
+ {\getrandomcount\scratchcounter{1}{5}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{.5em}{1.25em}%
+ \fakerule\scratchdimen}%
+ \space}%
+ \removeunwantedspaces
+ \egroup}
+
+\def\doshowfakewords#1%
+ {\bgroup
+ \setuppalet[fakerule]%
+ \definecolor[fakerulecolor]%
+ \dorecurse{#1}
+ {\getrandomcount\scratchcounter{1}{5}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{.5em}{1.25em}%
+ \color[fr\recurselevel c]{\fakerule\scratchdimen}}%
+ \space}%
+ \removeunwantedspaces
+ \egroup}
+
+\def\showfakewords{\let\dofakewords\doshowfakewords}
+
+\def\fakeword
+ {\fakewords{1}{1}} % no \plusone
+
+\def\fakeparindent
+ {\noindent
+ \ifindentation
+ \ifx\dofakedroppedcaps\relax
+ {\fakeparindentcolor
+ \vrule
+ \!!height \strutheight % not longer .5ex
+ \!!depth \strutdepth % not longer 0pt
+ \!!width \parindent}%
+ \else
+ \dofakedroppedcaps \let\dofakedroppedcaps\relax
+ \fi
+% \else
+% \dontleavehmode
+ \fi}
+
+\let\dofakedroppedcaps\relax
+
+\unexpanded\def\fakedroppedcaps#1%
+ {\ifnum#1>0
+ \def\dofakedroppedcaps
+ {\setbox\scratchbox\hbox
+ {\setbox\scratchbox\hbox{W}%
+ \scratchdimen#1\lineheight
+ \advance\scratchdimen -\lineheight
+ \advance\scratchdimen \dp\strutbox
+ \vrule
+ \!!width#1\wd\scratchbox
+ \!!height\ht\scratchbox
+ \!!depth\scratchdimen}%
+ \ht\scratchbox\ht\strutbox
+ \dp\scratchbox\dp\strutbox
+ \hangindent\wd\scratchbox
+ \advance\hangindent .5em
+ \wd\scratchbox\hangindent
+ \hangafter-#1\noindent
+ \llap{\fakeparindentcolor\box\scratchbox}}%
+ \fi}
+
+\newcounter\noffakedfigures
+
+\unexpanded\def\showfakefigure
+ {\donetrue\dodoubleempty\dofakefigure}
+
+\unexpanded\def\fakefigure
+ {\donefalse\dodoubleempty\dofakefigure}
+
+\def\dofakefigure[#1][#2]#3#4#5#6% [] [] minwidth maxwidth minheight maxheight
+ {\doglobal\increment\noffakedfigures
+ \ifdone
+ \endgraf
+ \hbox to \hsize
+ {\hss\fakeparindentcolor
+ \strut\bf Figure \noffakedfigures
+ \doifsomething{#1}{\space(#1)}%
+ \hss}
+ \endgraf
+ \fi
+ \getvalue{\e!place\v!figure}
+ [#1][#2]%
+ {\freezerandomseed
+ \let\endstrut\relax
+ \let\begstrut\relax
+ \doifinsetelse{#1}{\v!left,\v!right}
+ {\fakewords{2}{4}}
+ {\fakewords{4}{10}}}%
+ {\getrandomdimen{\dimen0}{#3}{#4}%
+ \getrandomdimen{\dimen2}{#5}{#6}%
+ \doifinset{#1}{\v!left,\v!right}
+ {\dimen0=.75\dimen0
+ \ifdim\dimen0>.6\hsize \dimen0=.5\hsize\fi
+ \ifdim\dimen0<.3\hsize \dimen0=.3\hsize\fi}%
+ \framed
+ [\c!width=\dimen0,
+ \c!height=\dimen2,
+ \c!frame=\v!off,
+ \c!background=\v!color,
+ \c!backgroundcolor=fakeparindentcolor]
+ {\bf\white#1}}%
+ \defrostrandomseed}
+
+\def\fakeformula
+ {\dimen0\zeropoint
+ \getrandomcount\scratchcounter{3}{6}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{1em}{3em}%
+ \mathinner{\red\fakerule\scratchdimen}%
+ \ifnum\recurselevel<\scratchcounter+\fi
+ \advance\scratchdimen\dimen0}%
+ =\mathinner{\red\fakerule\scratchdimen}}
+
+\def\fakespacingformula
+ {\color[fakebaselinecolor]{\ruledbaseline}\fakeformula}
+
+%D test \type{\bodyfontgrid}\space test
+%D test \type{\emexgrid} \space test
+
+\def\smashedgrid
+ {\dosingleempty\dosmashedgrid}
+
+\def\dosmashedgrid[#1]%
+ {\hsmashed
+ {\setbox\scratchbox=\hbox
+ {\basegrid
+ [\c!nx=10,\c!ny=10,\c!dx=1,\c!dy=1,
+ \c!unit=\bodyfontsize,#1]}%
+ \hbox to \zeropoint
+ {\hss\lower.5\ht\scratchbox\box\scratchbox\hss}%
+ \hbox to \zeropoint
+ {\hss
+ \black\vrule\!!width6\linewidth\!!height3\linewidth\!!depth3\linewidth
+ \hss}}}
+
+\def\bodyfontgrid
+ {\hbox
+ {{\linewidth.1pt\yellow\smashedgrid[\c!nx=30,\c!ny=30,\c!scale=.3333]}%
+ {\linewidth.2pt\green \smashedgrid[\c!nx=20,\c!ny=20,\c!scale=.5]}%
+ {\linewidth.3pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!scale=1]}}}
+
+\def\emexgrid
+ {\hbox
+ {{\linewidth.15pt\green\smashedgrid[\c!nx=20,\c!ny=20,\c!unit=ex]}%
+ {\linewidth.15pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!unit=em]}}}
+
+%D The next few macros are not really public and kind of low
+%D level. They are obscure and a bit perverse.
+
+\definecolor[llblack][s=0.01]
+
+\def\lowlevelstream#1#2#3%
+ {\ifinotr \else
+ \dontleavehmode
+ \prewordbreak
+ \bgroup\bgroup % make sure aftergroup stuff is handled
+ %\let#1#2\optimizetransparencyfalse\black
+ \infofont\clap{\vl}\ignorespaces#3\unskip\clap{\vl}%
+ \egroup\egroup
+ \prewordbreak
+ \fi
+ #2{#3}}
+
+\let\normalPDFcode\PDFcode
+
+\def\showlowlevelstream
+ {\def\PDFcode{\lowlevelstream\PDFcode\normalPDFcode}%
+ \def\special{\lowlevelstream\special\normalspecial}}
+
+\def\showlowlevelstreamonly
+ {\def\PDFcode{\lowlevelstream\PDFcode\gobbleoneargument}%
+ \def\special{\lowlevelstream\special\gobbleoneargument}}
+
+\startnotmode[mkiv]
+
+ \let\normaldostartgraymode \dostartgraymode
+ \let\normaldostartgraycolormode\dostartgraycolormode
+ \let\normaldostartrgbcolormode \dostartrgbcolormode
+ \let\normaldostartcmykcolormode\dostartcmykcolormode
+ \let\normaldostartspotcolormode\dostartspotcolormode
+
+ \def\traceddostartgraymode#1%
+ {#1\normaldostartgraymode{#1}}
+
+ \def\traceddostartgraycolormode#1%
+ {#1\normaldostartgraycolormode{#1}}
+
+ \def\traceddostartrgbcolormode#1#2#3%
+ {#1 #2 #3\normaldostartrgbcolormode{#1}{#2}{#3}}
+
+ \def\traceddostartcmykcolormode#1#2#3#4%
+ {#1 #2 #3 #4\normaldostartcmykcolormode{#1}{#2}{#3}{#4}}
+
+ \def\traceddostartspotcolormode#1#2%
+ {#1 #2\normaldostartspotcolormode{#1}{#2}}
+
+ \def\showcolormodes
+ {\let\dostartgraymode \traceddostartgraymode
+ \let\dostartgraycolormode\traceddostartgraycolormode
+ \let\dostartrgbcolormode \traceddostartrgbcolormode
+ \let\dostartcmykcolormode\traceddostartcmykcolormode
+ \let\dostartspotcolormode\traceddostartspotcolormode}
+
+\stopnotmode
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/ppchtex.mkii b/tex/context/modules/mkii/ppchtex.mkii
new file mode 100644
index 000000000..07ca9789a
--- /dev/null
+++ b/tex/context/modules/mkii/ppchtex.mkii
@@ -0,0 +1,3555 @@
+%D \module
+%D [ file=ppchtex (m-chemie),
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten}.
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% option=test => boxes
+% dummy => file
+% final => file / local run
+%
+% constante van phantom in definitie ONE: \setchemicaltextwidth 300
+%
+% it would be interesting to rewrite this module with todays
+% experiences and new context functionality, maybe ...
+
+% Deze module ondersteunt het zetten van chemische
+% (structuur)formules. Hoewel de macro' zijn afgestemd op
+% CONTEXT, zijn ze ook buiten deze zetomgeving te gebruiken.
+%
+% Dit is, afgezien van updates, de definitieve versie van
+% PPCHTEX. Gebruikersgemak, eenvoud, flexibiliteit, en
+% snelheid zijn inmiddels redelijk geoptimaliseerd. Dit neemt
+% niet weg dat hier en daar nog verbetering mogelijk is. Dit
+% zal dan ook nog gebeuren.
+%
+% Volgende versies zullen tenminste dezelfde functionaliteit
+% hebben. We houden ons natuurlijk het recht voor de kwaliteit
+% van de output te verbeteren. Daarnaast staan nog op het
+% wensenlijstje:
+%
+% - optimaliseren in termen van proces-tijd
+% - aanpassen naamgeving van interne macro's
+% - toevoegen van functionaliteit
+% - in \x!-vorm omzetten van GIVES, TB enz.
+%
+% De mix tussen engels en nederlands lijkt soms verwarrend.
+% Meestal zijn verborgen macro's engels en zichtbare macro's
+% nederlands. Het gebruik van [ ] en { } sluit aan op andere
+% Context-macro's. Hetzelfde geldt voor instellingen en
+% \start-\stop-constructies.
+%
+% De schijnbaar overbodige \bgroup-\egroup constructie
+% garandeert aansluiting bij de Context-macro's voor het
+% plaatsen van figuren, tabellen en andere floats.
+%
+% Binnen Context worden de macro's geladen met
+% \gebruikextras[chemie]. Daarbij wordt een passende melding
+% getoont. Buiten Context genereren we een melding:
+
+\doifundefined{usemodule}
+ {\writestatus{loading}{ConTeXt Chemical Macro's / 1996.3.1}}
+
+% Er kan gebruik worden gemaakt van PiCTeX of PStricks. Een
+% van deze pakketten moet van te voren zijn geladen.
+%
+% \input prepictex.tex (i.g.v. LaTeX)
+% \input pictex.tex
+% \input postpictex.tex (i.g.v. LaTeX)
+%
+% of:
+%
+% \input multido.tex
+% \input pstricks.tex
+% \input pst-plot.tex
+%
+% In \CONTEXT\ kan men de modules m-pictex en m-pstricks
+% gebruiken. De eerste module laad of efficiente wijze PiCTeX
+% en de tweede module koppelt het PSTRICKS kleurmechanisme
+% aan dat van \CONTEXT.
+%
+
+% PSTricks: {-\chemicalangle} instead of {*0}, which produces
+% faulty ps code when \chemicalangle=0
+
+\startcommands dutch english german
+
+ gotochemical: naarchemie gotochemical zurchemie
+ setupchemical: stelchemiein setupchemical stellechemieein
+ startchemical: startchemie startchemical startchemie
+ stopchemical: stopchemie stopchemical stopchemie
+ definechemical: definieerchemie definechemical definierechemie
+ chemical: chemie chemical chemie
+ toptext: boventekst toptext textueber
+ bottext: ondertekst bottext textunter
+ midtext: middentekst midtext textmitte
+
+\stopcommands
+
+\doifundefined{fiverm} % In the more recent LaTeX versions
+ {\font\fiverm=cmr5 } % \fiverm is no longer (pre)defined.
+
+\doifdefinedelse{beginpicture} % PiCTeX
+ {\doifdefinedelse{startMPdrawing}
+ {\chardef\chemicaldrawingmode=2 } % MetaPost
+ {\chardef\chemicaldrawingmode=0 }} % raw
+ {\doifdefinedelse{psaxes}
+ {\chardef\chemicaldrawingmode=1 } % PSTricks
+ {\chardef\chemicaldrawingmode=3 }} % unknown
+
+\ifcase\chemicaldrawingmode
+ \writestatus{ppchtex}{using PiCTeX}
+\or
+ \writestatus{ppchtex}{using PSTricks (still experimental)}
+ \writestatus{ppchtex}{automatic sizing not (yet) supported}
+\or
+ \writestatus{ppchtex}{using PiCTeX and MetaPost}
+\else
+ \writestatus{ppchtex}{load PiCTeX (+pre/post) or PSTricks (+pst_plot) first}
+ \bgroup
+ \read16 to \exit
+ \egroup
+ \expandafter\endinput
+\fi
+
+% De onderstaande help-informatie (%I) kan worden opgeroepen
+% in TeXEdit. De daaropvolgende setup-informatie (%S) kan
+% nadat zij is uit deze file is gefilterd met TeXUtil, in
+% handleidingen worden gebruikt. In deze file opgenomen
+% documentatie (%D en %M) kan worden gebruikt voor een
+% technische handleiding. Met %T kunnen templates worden
+% gedefinieerd voor TeXEdit.
+
+%I n=Chemie
+%I c=\stelchemiein,\chemie
+%I
+%I Chemische formules kunnen worden gezet met behulp van de
+%I onderstaande commando's:
+%I
+%I buiten $ en $$ :
+%I
+%I \chemie[segmenten][symbolen]
+%I
+%I \startchemie[instellingen]
+%I \chemie...
+%I \chemie...
+%I \stopchemie
+%I
+%I en binnen $ en $$:
+%I
+%I \chemie{}{}
+%I
+%I Voor tekst, uitleg en voorbeelde verwijzen we vooralsnog
+%I naar de handleiding.
+%P
+%I Het gedrag van de macro's kan worden ingesteld met:
+%I
+%I \stelchemiein[breedte=,hoogte=,links=,rechts=,boven=,
+%I onder=,korps=,schaal=,status=,assenstelsel=,kader=,
+%I variant=,optie=,formaat=,tekstformaat=,resolutie=,
+%I offset=,letter=]
+%I
+%I Structuren kunnen worden voorgedefinieerd met het commando
+%I
+%I \definieerchemie[naam]{\chemie...}
+
+%S \startsetup
+%S \command
+%S [\!stelchemiein]
+%S \type
+%S [\c!vars!]
+%S \variable
+%S [\c!breedte]
+%S [\c!number!,\v!passend]
+%S [0]
+%S \variable
+%S [\c!hoogte]
+%S [\c!number!,\v!passend]
+%S [0]
+%S \variable
+%S [\c!links]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!rechts]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!boven]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!onder]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!resolutie]
+%S [\c!number!]
+%S [\outputresolution]
+%S \variable
+%S [\c!korps]
+%S [10pt,11pt,12pt]
+%S [\bodyfontsize]
+%S \variable
+%S [\c!schaal]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!middel]
+%S \variable
+%S [\c!formaat]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!groot]
+%S \variable
+%S [\c!tekstformaat]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!groot]
+%S \variable
+%S [\c!status]
+%S [\v!start,\v!stop]
+%S [\v!start]
+%S \variable
+%S [\c!kader]
+%S [\v!aan,\v!uit]
+%S [\v!uit]
+%S \variable
+%S [\c!assenstelsel]
+%S [\v!aan,\v!uit]
+%S [\v!uit]
+%S \variable
+%S [\c!optie]
+%S [\v!test]
+%S []
+%S \variable
+%S [\c!variant]
+%S [1,2]
+%S [1]
+%S \variable
+%S [\c!offset]
+%S [HIGH,LOW]
+%S [LOW]
+%S \variable
+%S [\c!letter]
+%S [\c!command!]
+%S [\rm]
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [\v!startchemie]
+%S \type
+%S [\c!vars!\c!stp!]
+%S \inheritvariable
+%S [\v!stelchemiein]
+%S []
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [\v!chemie]
+%S \type
+%S [\c!vals!\c!vals!]
+%S \value
+%S [\c!list!]
+%S []
+%S \value
+%S [\c!list!]
+%S []
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [definieerchemie]
+%S \type
+%S [\c!val!\c!arg!]
+%S \value
+%S [\c!text!]
+%S []
+%S \stopsetup
+
+\unprotect
+
+% Om te voorkomen dat sub- en superscripts botsen passen we
+% wat fontdimen's aan (Knuth, The TeXBook, p179). Helaas
+% kunnen deze instellingen niet lokaal worden gehouden door
+% groeperen, vandaar dat een en ander moet worden geset n
+% gereset.
+%
+% Er dient een relatie te worden gelegd met de afmetingen
+% van de letters. In een eerdere versie werden daartoe de
+% \fontdimen's opgehoogd. Omdat dit problemen gaf bij
+% scaled fonts, is bij nader inzien gekozen voor de
+% onderstaande oplossing, waarbij de nieuwe waarden worden
+% afgeleid van de x-height (\fontexheight). De factor 0.70
+% is min of meer experimenteel vastgesteld. Soms worden de
+% regels iets verder uit elkaar gezet. Jammer. Italic fonts
+% hebben grotere cijfers en vallen min of meer uit de boot.
+
+\newif\ifloweredsubscripts
+
+% Due to some upward incompatibality of LaTeX to LaTeX2.09
+% and/or LaTeX2e we had to force \@@dochemicalstyle. Otherwise
+% some weird \nullfont error comes up.
+
+\def\beginlatexmathmodehack
+ {\ifmmode
+ \let\endlatexmathmodehack=\relax
+ \else
+ \def\endlatexmathmodehack{$}$\@@dochemicalstyle\empty
+ \fi}
+
+\def\setsubscripts%
+ {\beginlatexmathmodehack
+ \def\dosetsubscript##1##2##3%
+ {\dimen0=##3\fontexheight##2%
+ \setxvalue{@@\string##1\string##2}{\the##1##2\relax}%
+ ##1##2=\dimen0\relax}%
+ \def\dodosetsubscript##1##2%
+ {\dosetsubscript{##1}{\textfont 2}{##2}%
+ \dosetsubscript{##1}{\scriptfont 2}{##2}%
+ \dosetsubscript{##1}{\scriptscriptfont2}{##2}}%
+ %dodosetsubscript\mathsupnormal {?}%
+ \dodosetsubscript\mathsubnormal {.7}%
+ \dodosetsubscript\mathsubcombined{.7}%
+ \global\loweredsubscriptstrue
+ \endlatexmathmodehack}
+
+\def\resetsubscripts
+ {\ifloweredsubscripts
+ \beginlatexmathmodehack
+ \def\doresetsubscript##1##2%
+ {\dimen0=\getvalue{@@\string##1\string##2}\relax
+ ##1##2=\dimen0}%
+ \def\dodoresetsubscript##1%
+ {\doresetsubscript{##1}{\textfont2}%
+ \doresetsubscript{##1}{\scriptfont2}%
+ \doresetsubscript{##1}{\scriptscriptfont2}}%
+ %dodoresetsubscript\mathsupnormal
+ \dodoresetsubscript\mathsubnormal
+ \dodoresetsubscript\mathsubcombined
+ \global\loweredsubscriptsfalse
+ \endlatexmathmodehack
+ \fi}
+
+\ifx\Umathchar\undefined \else
+ % for the moment we nil them, soon we will have a proper
+ % way to deal with this
+ \let\setsubscripts \relax
+ \let\resetsubscripts\relax
+\fi
+
+\def\doresetsubscripts
+ {\resetsubscripts}
+
+\def\sethighsubscripts
+ {\resetsubscripts
+ \let\dosetsubscripts=\relax}
+
+\def\setlowsubscripts
+ {\def\dosetsubscripts{\setsubscripts}}
+
+\setlowsubscripts
+
+\newcount\horchemical % t.z.t. \newcounter
+\newcount\verchemical % t.z.t. \newcounter
+\newcount\txtchemical % t.z.t. \newcounter
+\newcount\levchemical % t.z.t. \newcounter
+
+\newif\ifinchemical \inchemicalfalse
+\newif\iffixedchemical \fixedchemicalfalse
+
+\newbox\chemicalsymbols
+
+% Eigenlijk moeten de constanten en variabelen in cont-nl.tex
+% staan. Dit pakket is echter relatief onafhankelijk van CONTEXT.
+
+\definesystemvariable {chemical}
+
+\definesystemconstant {chemical}
+
+\definesystemconstant {translate}
+\definesystemconstant {distance}
+\definesystemconstant {mirror}
+\definesystemconstant {rotate}
+\definesystemconstant {substitute}
+\definesystemconstant {angle}
+
+\definesystemconstant {executechemical}
+\definesystemconstant {chemicaltextelement}
+\definesystemconstant {chemicallinesegment}
+\definesystemconstant {chemicalcircsegment}
+
+\def\chemicalspace {\quad}
+
+% begin van experiment:
+%
+% De onderstaande twee macro's kunnen worden gebruikt voor
+% bijvoorbeeld een interactiemechanisme.
+%
+% \localgotochemical {verwijzing} {tekst}
+% \localthisischemical {verwijzing}
+
+\def\dowithchemical%
+ {}
+
+\doifdefinedelse{@@iastate}
+ {\def\localgotochemical#1#2{\naarbox{#2}[#1]}%
+ \def\localthisischemical#1{\pagereference[#1]}}
+ {\def\localgotochemical#1{}%
+ \def\localthisischemical#1{}}
+
+% eind van experiment
+
+\def\setchemicalmaximum #1
+ {\def\maxchemical{#1}}
+
+\def\doifchemicalnumber#1#2#3%
+ {\doifnumberelse{#1}
+ {\ifnum#1>\maxchemical\relax
+ \writestatus{ppchtex}{number #1 is skipped}%
+ \else
+ #3%
+ \fi}
+ {\unknownchemical{#2}}}%
+
+\newif\ifsmallchemicaltext
+
+\let\@@localchemicalstyle\empty
+
+\def\setupchemicalformat[#1]%
+ {\processaction
+ [\getvalue{#1\c!size}]
+ [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle},
+ \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi},
+ \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi},
+ \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]%
+ \processaction
+ [\getvalue{#1\c!textsize}]
+ [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle},
+ \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi},
+ \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi},
+ \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]%
+ \processaction
+ [\getvalue{#1\c!scale}]
+ [ \v!small=>\def\@@localchemicalscale{500},
+ \v!medium=>\def\@@localchemicalscale{625},
+ \v!big=>\def\@@localchemicalscale{750},
+ \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]}
+
+\def\@@currentchemicalformat
+ {\ifinchemical
+ \@@localchemicalformat
+ \else
+ \@@localchemicalstyle
+ \fi}
+
+\def\dosetupchemical[#1]%
+ {\getparameters[\??chemical\s!chemical][#1]%
+ \doifelse{\@@chemicalchemicaloffset}{LOW}
+ {\setlowsubscripts}
+ {\sethighsubscripts}%
+ \setupchemicalformat[\??chemical\s!chemical]%
+ \ignorespaces}
+
+\def\setupchemical
+ {\dosingleargument\dosetupchemical}
+
+\def\@@dochemicalstyle% % default mapping
+ {\@@chemicalstyle}
+
+\def\@@dochemicalcolor% % no mapping yet
+ {}
+
+\def\@@chemicalstyle % $inner-style$ % (overloaded)
+ {\@@chemicalchemicalstyle} % $$outer-style$$
+
+\def\@@writechemicalstate#1#2%
+ {}
+
+\def\@@beginchemicallocalpicture
+ {\ifcase\chemicaldrawingmode
+ \beginpicture
+ \or
+ \pspicture(0,0)(0,0) % is this permitted ?
+ \or
+ \pushMPdrawing
+ \startMPdrawing
+ %prologues := 1 ;
+ %input mp-tool ;
+ u := 10*\@@chemicalunit;
+ bboxmargin := 0pt ;
+ pickup pencircle scaled 2u ; % ???
+ \stopMPdrawing
+ \beginpicture
+ \fi}
+
+\def\@@endchemicallocalpicture#1#2%
+ {\ifcase\chemicaldrawingmode
+ \endpicture
+ \or
+ \endpspicture
+ \or
+ \resetchemicalcoordinates
+ \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}%
+ \wd2=\!!zeropoint
+ \ht2=\!!zeropoint
+ \dp2=\!!zeropoint
+ \put {\box2} at 0 0
+ \endpicture
+ \popMPdrawing
+ \fi}
+
+\def\@@beginchemicalpicture#1#2#3#4%
+ {\ifnum\chemicaldrawingmode=1
+ \pspicture(#1,#3)(#2,#4)%
+ \def\account##1##2{}%
+ \psaxes[axesstyle=none,labels=none,ticks=none](#1,#3)(#2,#4)%
+ \else
+ \beginpicture
+ \setplotarea
+ x from {#1} to {#2},
+ y from {#3} to {#4}
+ \iffixedchemical
+ \accountingon
+ \def\account##1##2%
+ {\put {} at {##1} {##2} }%
+ \else
+ \accountingoff
+ \def\account##1##2{}%
+ \fi
+ \fi
+ \ignorespaces}
+
+\def\@@endchemicalpicture%
+ {\ifcase\chemicaldrawingmode
+ \put {\box\chemicalsymbols} at 0 0 % elders
+ \endpicture
+ \or
+ \rput(0,0){\box\chemicalsymbols}%
+ \endpspicture
+ \or
+ \put {\box\chemicalsymbols} at 0 0 % elders
+ \ifMPdrawingdone
+ \resetchemicalcoordinates
+ \setbox2\hbox{\MPshiftdrawingtrue\MPstaticgraphictrue\getMPdrawing}%
+ \wd2=\!!zeropoint
+ \ht2=\!!zeropoint
+ \dp2=\!!zeropoint
+ \put {\box2} at 0 0 %
+ \fi
+ \endpicture
+ \fi}
+
+\def\@@setchemicalcoordinatesystem#1%
+ {\edef\@@chemicalunit{#1}%
+ \ifcase\chemicaldrawingmode
+ \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> %
+ \or
+ \psset{unit=\@@chemicalunit}%
+ \or
+ \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> %
+ \startMPdrawing
+ %input mp-tool ;
+ %prologues := 1 ;
+ u := 10*#1;
+ bboxmargin := 0pt ;
+ pickup pencircle scaled 2u ; % ???
+ \stopMPdrawing
+ \fi}
+
+\ifx\MPdivten\undefined % hack to prevent overflows in mp
+ \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax}
+\fi
+
+\def\@@setchemicalaxis#1#2#3#4%
+ {\ifcase\chemicaldrawingmode
+ \axis
+ bottom shiftedto y=0
+ ticks from {#1} to {#2} by 500 /
+ \axis
+ left shiftedto x=0
+ ticks from {#3} to {#4} by 500 / %
+ \or
+ \psaxes[labels=none,Dx=500,Dy=500](0,0)(#1,#3)(#2,#4)%
+ \or
+ \global\MPdrawingdonetrue
+ % we need to div beforehand because of mp limitations
+ \startMPdrawing
+ x1 := \MPdivten[#1]u ; x2 := \MPdivten[#2]u;
+ y1 := \MPdivten[#3]u ; y2 := \MPdivten[#4]u;
+ draw z1--(x2,y1)--z2--(x1,y2)--cycle ;
+ d := 50u ; dd := 10u ;
+ draw (x1,0)--(x2,0) ;
+ draw (0,y1)--(0,y2) ;
+ for i=d step -d until x1: draw (i,dd)--(i,-dd) ; endfor ;
+ for i=d step d until x2: draw (i,dd)--(i,-dd) ; endfor ;
+ for i=d step -d until y1: draw (-dd,i)--(dd,i) ; endfor ;
+ for i=d step d until y2: draw (-dd,i)--(dd,i) ; endfor ;
+ \stopMPdrawing
+ \fi}
+
+\def\@@setsecondchemicalplotsymbol%
+ {\ifcase\chemicaldrawingmode
+ \!!widtha=50.8mm
+ \divide\!!widtha by \@@chemicalresolution\relax
+ \plotsymbolspacing=\!!widtha
+ \setplotsymbol({\vrule\!!height\!!widtha\!!width\!!widtha})%
+ \fi}
+
+% Something for Dirk:
+
+\newcount \currentchemical
+
+%\newif \ifskipchemical
+
+\def\setchemicaldimensions#1#2#3%
+ {\bgroup
+ \global\advance\currentchemical by 1
+ \dimen0=#1\relax
+ \dimen2=#2\relax
+ \dimen4=#3\relax
+ \setxvalue{chemical::\the\currentchemical}%
+ {\noexpand\docommand{\the\dimen0}{\the\dimen2}{\the\dimen4}}%
+ \egroup}
+
+%\def\getchemicaldimensions#1#2#3%
+% {\global\advance\currentchemical by 1
+% \def\docommand##1##2##3%
+% {#1=##1\relax#2=##2\relax#3=##3\relax}%
+% \doifdefinedelse{chemical::\the\currentchemical}
+% {\getvalue{chemical::\the\currentchemical}}
+% {\docommand{6cm}{4cm}{0cm}}}
+%
+%\def\savechemicaldimensions%
+% {\bgroup
+% \writestatus{ppchtex}{saving dimensions in ppchtex.dim}%
+% \def\docommand##1##2##3%
+% {\immediate\write\scratchwrite
+% {\noexpand\setchemicaldimensions{##1}{##2}{##3}}}%
+% \immediate\openout\scratchwrite=ppchtex.dim
+% \scratchcounter=0
+% \loop
+% \ifnum\scratchcounter<\currentchemical
+% \advance\scratchcounter by 1
+% \getvalue{chemical::\the\scratchcounter}%
+% \repeat
+% \immediate\closeout\scratchwrite
+% \egroup}
+%
+%\def\loadchemicaldimensions% oh, how nice it would be to use
+% {\bgroup % one of the context read commands
+% \global\currentchemical=0
+% \immediate\openin\scratchread=./ppchtex.dim
+% \ifeof\scratchread
+% \immediate\closein\scratchread
+% \global\skipchemicalfalse
+% \else
+% \immediate\closein\scratchread
+% \input ./ppchtex.dim\relax
+% \ifnum\currentchemical>0
+% \writestatus{ppchtex}{loading dimensions from ppchtex.dim}%
+% \global\skipchemicaltrue
+% \else
+% \global\skipchemicalfalse
+% \fi
+% \global\currentchemical=0
+% \global\let\savechemicaldimensions=\relax
+% \fi
+% \egroup
+% \global\let\loadchemicaldimensions=\relax}
+
+\ifx\normalchemicalframe\undefined
+ \let\normalchemicalframe\hbox % hook for educational purposes
+\fi
+
+\unexpanded\def\complexstartchemical[#1]%
+ {\copyparameters
+ [\??chemical][\??chemical\s!chemical]
+ [\c!width,\c!height,\c!left,\c!right,\c!top,\c!bottom,
+ \c!bodyfont,\c!size,\c!scale,\c!state,\c!frame,\c!axis,\c!factor,
+ \c!location,\c!option,\c!alternative,\c!resolution,\c!offset,\c!style,
+ \c!color,\c!rulecolor,\c!rulethickness]%
+ \getparameters
+ [\??chemical]
+ [#1]%
+ %
+ \setupchemicalformat[\??chemical]%
+ %
+ \ifnum\chemicaldrawingmode=2
+ \resetMPdrawing
+ \fi
+ %
+ \doif{\@@chemicalalternative}{2}
+ {\@@setsecondchemicalplotsymbol}%
+ %
+ \doif{\@@chemicalaxis}\v!on
+ {\let\chemicalframe\hbox}%
+ %
+ \!!counta=250000
+ \divide\!!counta by \@@localchemicalscale
+ \!!widtha=\@@chemicalbodyfont
+ \divide\!!widtha by \!!counta
+ \@@setchemicalcoordinatesystem{\the\!!widtha}%
+ %
+ % \!!counta = -x \!!countc = -y
+ % \!!countb = +x \!!countd = +y
+ %
+ \def\calculateaxis##1##2##3##4##5%
+ {##1=##3\relax
+ ##2=##4\relax
+ \ifnum##5=0
+ \ifnum##3=0
+ \ifnum##4=0
+ ##1=2000
+ ##2=2000
+ \fi
+ \fi
+ \else
+ \ifnum##3=0
+ \ifnum##4=0
+ ##1=##5\relax
+ \divide##1 by 2
+ ##2=##1\relax
+ \else
+ ##1=##5\relax
+ \advance##1 by -##2\relax
+ \fi
+ \else
+ \ifnum##4=0
+ ##2=##5\relax
+ \advance##2 by -##1\relax
+ \fi
+ \fi
+ \fi}%
+ \fixedchemicalfalse
+ \doif\@@chemicalwidth\v!fit
+ {\edef\@@chemicalwidth
+ {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}%
+ \fixedchemicaltrue}%
+ \doif\@@chemicalheight\v!fit
+ {\edef\@@chemicalheight
+ {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}%
+ \fixedchemicaltrue}%
+ \doifelse\@@chemicallocation\v!intext
+ {\!!counta=0 \!!countb=0
+ \!!counta=0 \!!countd=0 }
+ {\calculateaxis
+ \!!counta\!!countb
+ \@@chemicalleft\@@chemicalright\@@chemicalwidth
+ \calculateaxis
+ \!!countc\!!countd
+ \@@chemicalbottom\@@chemicaltop\@@chemicalheight}%
+ %
+ \edef\@@chemheight {\the\!!countc}%
+ \edef\@@chemdepth {\the\!!countd}%
+ \edef\@@chemicaltop {\the\!!countc}%
+ \edef\@@chemicalbottom{\the\!!countd}%
+ %
+ \doifinsetelse\v!on{\@@chemicalframe,\@@chemicalaxis}
+ {\def\@@chemicalborder{\chemicalframe}}
+ {\def\@@chemicalborder{\normalchemicalframe}}%
+ %
+ \setbox0=\hbox\bgroup % this was a \vbox which took \hsize
+ %
+ \@@beginchemicalpicture
+ {-\the\!!counta}{\the\!!countb}
+ {-\the\!!countc}{\the\!!countd}%
+ \doif{\@@chemicalstate}\v!start
+ {\doif\@@chemicalaxis\v!on
+ {\@@setchemicalaxis
+ {-\the\!!counta}{\the\!!countb}
+ {-\the\!!countc}{\the\!!countd}}}%
+ \doifelse\@@chemicaloption\v!test
+ {\def\@@writechemicalstate##1##2%
+ {\convertargument##2\to\ascii
+ \writestatus{##1}{\ascii}}}
+ {\def\@@writechemicalstate##1##2{}}%
+ \ignorespaces}
+
+\def\dostartchemical%
+ {\catcode`\^=\@@superscript% t.b.v. \enableduplication
+ \catcode`\_=\@@subscript % t.b.v. de zekerheid
+ \begingroup
+ \inchemicaltrue
+ \def\toptext##1{\gdef\thetoptext{##1}\ignorespaces}\toptext{}%
+ \def\bottext##1{\gdef\thebottext{##1}\ignorespaces}\bottext{}%
+ \def\midtext##1{\gdef\themidtext{##1}\ignorespaces}\midtext{}%
+ \def\@@chemicalpostponed{}%
+ \complexorsimpleempty\startchemical}
+
+\def\startchemical
+ {\bgroup % t.b.v. ungrouped floats
+% \loadchemicaldimensions
+% \ifskipchemical
+% \def\dostartchemical%
+% {\def\dummy[####1]{}\dosingleempty\dummy}%
+% \def\chemical%
+% {\def\dummy[####1][####2][####3]{}\dotripleempty\dummy}%
+% \def\toptext##1{}%
+% \def\midtext##1{}%
+% \def\bottext##1{}%
+% \fi
+ \dostartchemical}
+
+\def\stopchemical
+ {%\ifskipchemical
+ % \getchemicaldimensions{\dimen0}{\dimen2}{\dimen4}%
+ % \dimen8=\dimen2\advance\dimen8 by \dimen4
+ % \setbox0=\vbox to \dimen8
+ % {\vss\hbox to \dimen0{\hss\the\currentchemical\hss}\vss}%
+ % \wd0=\dimen0\ht0=\dimen2\dp0=\dimen4
+ % \chemicalframe{\box0}%
+ %\else
+ \checkchemicalpicture
+ \@@endchemicalpicture
+ \egroup
+ \ifnum\chemicaldrawingmode=1
+ \dimen0=\@@chemicalunit
+ \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}%
+ \ht0=\@@chemheight\dimen0
+ \dp0=\@@chemdepth\dimen0
+ \fi
+ \dimen0=\ht0
+ \advance\dimen0 by \dp0
+ \inchemicalfalse % enables \chemie{} in text
+ \setbox4=\alignedchemical\themidtext
+ \setbox6=\alignedchemical\thetoptext
+ \setbox8=\alignedchemical\thebottext
+ \setbox4=\hbox to \wd0
+ {\strut\hss$\vcenter{\box4}$\hss}%
+ \setbox2=\vbox to \dimen0
+ {\hbox to \wd0{\strut\hss\box6\hss}
+ \vfill
+ \hbox to \wd0{\strut\hss\box8\hss}
+ \vss}% disables the depth
+ \wd0=0pt \wd4=0pt
+ \ht2=\ht0 \dp2=\dp0
+ \ht4=\ht0 \dp4=\dp0
+ %\setchemicaldimensions{\wd2}{\ht2}{\dp2}%
+ \@@chemicalborder{\box0\box4\box2}% text on top of chemicals
+ \endgroup
+ %\fi
+ \ignorespaces
+ \egroup} % t.b.v. ungrouped floats
+
+\def\alignedchemical#1%
+ {\vtop
+ {\def\par{\egroup\hbox\bgroup\strut}%
+ \let\\=\par
+ \let\endgraf=\par
+ \hbox\bgroup\strut#1\egroup}}
+
+% \setchemicalcoordinates{#1}{#2}
+%
+% #1: verplaatsing in x-richting
+% #2: verplaatsing in y-richting
+
+\newif\ifchemicaldirection
+
+\def\checkchemicaldirection#1#2%
+ {\ifchemicaldirection
+ \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi
+ \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi
+ \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi
+ \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi
+ \chemicaldirectionfalse
+ \fi}
+
+\def\processchemicaldirection%
+ {\chemicaldirectiontrue\processchemicaltranslate}
+
+\def\setchemicalcoordinates#1#2%
+ {\advance\horchemical #1\relax
+ \advance\verchemical #2\relax
+ \checkchemicaldirection{#1}{#2}%
+ \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}%
+ \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at {\the\horchemical} {\the\verchemical}
+ \fi}
+
+\def\resetchemicalcoordinates
+ {\horchemical=0
+ \verchemical=0
+ \edef\chemicalxoffset{0}%
+ \edef\chemicalyoffset{0}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at 0 0
+ \fi}
+
+\def\restorechemicalcoordinates
+ {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}%
+ \edef\chemicalxoffset{\the\horchemical}%
+ \edef\chemicalyoffset{\the\verchemical}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at {\the\horchemical} {\the\verchemical}
+ \fi}
+
+\def\setchemicaltranslate #1 #2 #3
+ {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}}
+
+\def\processchemicaltranslate#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{MOV#1}
+ {\ifnum##1=0
+ \def\chemicaloffset{0}% incompatible change
+ \resetchemicalcoordinates
+ \else
+ \getvalue{\s!translate##1}%
+ \dochemicaloffset{##1}%
+ \def\chemicaloffset{0}%
+ \fi}}%
+ \doprocess[#1]}
+
+\def\setchemicaldistance #1
+ {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}%
+ \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}%
+ \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}%
+ \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}}
+
+\def\setchemicaldirection #1
+ {\def\chemicaldirection{#1}}
+
+\def\processchemicaldistance#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{ADJ#1}
+ {\ifnum##1=0
+ \resetchemicalcoordinates
+ \else
+ \def\@@chemicalpostponed{\getvalue{\s!distance##1}}%
+ \@@chemicalpostponed
+ \fi}}%
+ \doprocess[#1]}
+
+\def\setchemicalsubstitute #1
+ {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}%
+ \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}%
+ \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}%
+ \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}}
+
+\def\processchemicalsubstitute#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{SUB#1}
+ {\ifnum##1=0
+ \resetchemicalcoordinates
+ \else
+ \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}%
+ \@@chemicalpostponed
+ \fi}}%
+ \doprocess[#1]}
+
+% Het is mogelijk een offset of move meerdere malen uit te
+% voeren, door een nummer voor het commando te plaatsen.
+
+\def\chemicalrepeat {1}
+
+\def\redoprocesschemical[#1#2]%
+ {\doifinstringelse{#1}{0123456789.}
+ {\edef\chemicalrepeat{\chemicalrepeat#1}%
+ \redoprocesschemical[#2]}
+ {\processchemical[#1#2]%
+ \def\chemicalrepeat{1}}}
+
+\def\doprocesschemical[#1#2]#3%
+ {\doifinstringelse{#1}{0123456789.}
+ {\def\chemicalrepeat{#1}%
+ \redoprocesschemical[#2]}
+ {#3}}
+
+% \dochemicaloffset{#1}
+%
+% #1: binding
+
+\def\chemicaloffset{0}
+
+\def\processchemicaloffset#1%
+ {\dimen0=62500 sp % real calc on cardinals, funny number
+ \dimen0=\chemicalrepeat\dimen0
+ \divide\dimen0 by \@@localchemicalscale
+ \!!counta=\dimen0
+ \def\doprocess[##1##2]%
+ {\doifinstringelse{##1}{128}
+ {\edef\chemicaloffset{\the\!!counta}}
+ {\doifinstringelse{##1}{456}
+ {\edef\chemicaloffset{-\the\!!counta}}
+ {\doifelse{##1}{0}
+ {\edef\chemicaloffset{0}}
+ {\unknownchemical{OFF#1}}}}}%
+ \doprocess[#1]}
+
+\def\dochemicaloffset#1%
+ {\ifnum\chemicaloffset=0
+ \def\undochemicaloffset{}%
+ \else
+ \setchemicalcoordinates{-\chemicaloffset}{0}%
+ \def\undochemicaloffset%
+ {\setchemicalcoordinates{\chemicaloffset}{0}%
+ \def\undochemicaloffset{}}%
+ \fi}
+
+\def\processchemicalphantom#1#2%
+ {\setbox0=\hbox
+ {\def\splitoff##1????{##1}%
+ $\@@dochemicalstyle{\@@localchemicalformat\splitoff#2}$}%
+ \dimen0=.25\wd0
+ \divide\dimen0 by \@@localchemicalscale
+ \!!counta=\dimen0
+ \doifinstringelse{#1}{128}
+ {\edef\chemicaloffset{\the\!!counta}}
+ {\doifinstringelse{#1}{456}
+ {\edef\chemicaloffset{-\the\!!counta}}
+ {\doifelse{#1}{0}
+ {\edef\chemicaloffset{0}}
+ {\unknownchemical{OF#1:#2}}}}}
+
+% \dosetchemicalrotation{#1}{#2}
+%
+% #1: cos(phi)
+% #2: sin(phi)
+
+\def\chemicalrotation {1}
+\def\chemicalangle {0}
+\def\chemicalxoffset {0}
+\def\chemicalyoffset {0}
+
+\def\setchemicalmirror#1%
+ {\setvalue{\s!mirror#1}{*}}
+
+\def\resetchemicalmirror#1%
+ {\resetvalue{\s!mirror#1}}
+
+\def\togglechemicalmirror#1%
+ {\doifelse{\getvalue{\s!mirror#1}}{*}
+ {\resetchemicalmirror{#1}}
+ {\setchemicalmirror{#1}}}
+
+\def\setchemicalrotation #1 #2 #3 #4 #5 #6 #7 #8 #9
+ {\setvalue{\s!rotate1.#1}{\dosetchemicalrotation{#2}{#3}}%
+ \setvalue{\s!rotate2.#1}{\dosetchemicalrotation{#4}{#5}}%
+ \setvalue{\s!rotate3.#1}{\dosetchemicalrotation{#6}{#7}}%
+ \setvalue{\s!rotate4.#1}{\dosetchemicalrotation{#8}{#9}}}
+
+\def\setchemicalangle #1 #2 #3 #4 #5
+ {\setvalue{\s!angle1.#1}{\dosetchemicalangle{#2}}%
+ \setvalue{\s!angle2.#1}{\dosetchemicalangle{#3}}%
+ \setvalue{\s!angle3.#1}{\dosetchemicalangle{#4}}%
+ \setvalue{\s!angle4.#1}{\dosetchemicalangle{#5}}}
+
+\def\chemicalrotate[#1]%
+ {\doifdefinedelse{\s!mirror#1}
+ {\getvalue{\s!rotate\chemicalrotation.#1\getvalue{\s!mirror#1}}%
+ \getvalue{\s!angle\chemicalrotation.#1\getvalue{\s!mirror#1}}}
+ {\getvalue{\s!rotate\chemicalrotation.#1}%
+ \getvalue{\s!angle\chemicalrotation.#1}}}
+
+\def\dosetchemicalangle#1% zwak zie onder
+ {\def\chemicalangle{#1}}
+
+\def\dosetchemicalrotation#1#2%
+ {\ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \startrotation by {#1} {#2} %% \stoprotation (t.b.v. testen)
+ \fi}
+
+\def\doresetchemicalrotation
+ {\ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \stoprotation
+ \fi}
+
+\def\processchemicalrotation#1%
+ {\def\doprocess[##1##2]%
+ {\doifnumberelse{##1}
+ {\def\chemicalrotation{##1}}
+ {\unknownchemical{ROT#1}}}%
+ \doprocess[#1]}
+
+% \filtertextelement[#1][#2][#3][#4]
+%
+% #1: volgnummer
+% #2: offset in uitlijningen
+% #3: lijst met uitlijningen -> \chemicalloca
+% #4: lijst met teksten -> \chemicaltext
+
+\def\setchemicallocation#1%
+ {\doifelse{#1}{}
+ {\edef\chemicalloca{c}}
+ {\edef\chemicalloca{#1}}}
+
+\newif\iffixedchemicaltext
+
+\def\filterchemicaltextelement[#1][#2][#3][#4]%
+ {\ifchemicaltextconstant
+ \def\chemicaltext{#4}%
+ \setchemicallocation{}%
+ \else
+ \ifnum#1=0\relax
+ \setchemicallocation{}%
+ \else
+ \iffixedchemicaltext
+ \!!counta#2
+ \else
+ \!!counta=\chemicalrotation
+ \advance\!!counta -1
+ \multiply\!!counta #2
+ \advance\!!counta #1
+ \fi
+ \getfromcommalist[#3][\the\!!counta]%
+ \setchemicallocation\commalistelement
+ \fi
+ \ifchemicalpicture
+ \let\chemicaltext\relax
+ \else
+ \advance\txtchemical 1
+ \getfromcommalist[#4][\txtchemical]%
+ \let\chemicaltext\commalistelement
+ \fi
+ \fi
+ \fixedchemicaltextfalse}
+
+% \putchemicaltext{#1}{#2}
+%
+% #1 : x-coordinaat
+% #2 : y-coordinaat
+%
+% \chemicaltext en \chemicalloca worden met \gettextelement
+% opgehaald uit de tweede set bij \chemie
+%
+% Ten behoeve van testdoeleinden wordt gebruik gemaakt van
+% \chemicalframe in plaats van het meer sjieke, maar tevens
+% meer trage \framed.
+
+\ifx\ruledhbox\undefined
+ \def\chemicalframe#1%
+ {\hbox
+ {\vrule\hskip-.4pt
+ \vbox{\hrule\vskip-.4pt\hbox{#1}\vskip-.4pt\hrule}%
+ \hskip-.4pt\vrule}}
+\else
+ \def\chemicalframe#1%
+ {\ruledhbox{#1}}
+\fi
+
+\def\doputchemicaltext#1 [#2] at #3 #4 %
+ {\ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[#2]{\chemicalangle}(#3,#4){#1}}}%
+ \else
+ \put {#1} [#2] at {#3} {#4} %
+ \fi}
+
+\def\dodoifsinglelocation#1#2\\#3%
+ {\ifx#2\relax#3\fi}
+
+\def\doifsinglelocationelse#1%
+ {\expandafter\dodoifsinglelocationelse#1\relax\\}
+
+\def\putchemicaltext#1#2%
+ {\enablechemicalspecials
+ \ifchemicalpicture
+ \setchemicalpicture{#1}{#2}%
+ \else
+ \doifelse\@@chemicaloption\v!test
+ {\def\@@chemicalframe{\chemicalframe}}
+ {\def\@@chemicalframe{}}%
+ \dosetsubscripts
+ \setbox2=\hbox{\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@localchemicalformat \chemicaltext}$}%
+ \setbox4=\hbox{$\@@dochemicalstyle{\@@localchemicalformat C_2^2}$}%
+ \setbox6=\hbox{$\@@dochemicalstyle{\@@localchemicalformat O}$}% or C
+ \doresetsubscripts
+ \doifnot\@@chemicallocation\v!intext
+ {\ht2=\ht4
+ \dp2=\dp4}%
+ \setbox2=\hbox{\@@chemicalframe{\box2}}%
+ \ifdim\wd2>\wd6
+ \doifelse{#1}{0}
+ {\doifnot{#2}{0}{\wd2=\wd6}}
+ {%\doifsinglelocation\chemicalloca
+ {\doifinset{\chemicalloca}{t,b}{\wd2=\wd6}}}% common ?
+ \fi
+ \expanded
+ {\doputchemicaltext
+ {\noexpand\dowithchemical{\copy2}} % per se \copy2 i.p.v. \box2
+ [\chemicalloca] at {#1} {#2} }
+ \nomoreaccounting
+ \fi
+ \disablechemicalspecials}
+
+\def\setchemicaltextelement #1 #2 #3
+ {\setvalue{\s!chemicaltextelement#1}{\putchemicaltext{#2}{#3}}}
+
+\def\getchemicalfixedtextelement%
+ {\fixedchemicaltexttrue
+ \getchemicaltextelement}
+
+\def\getchemicaltextelement[#1][#2][#3][#4][#5]%
+ {\filterchemicaltextelement[#2][#3][#4][#5]%
+ \doifelse{#2}{0}
+ {\dochemicaloffset{#2}% % incompatible change
+ \putchemicaltext{0}{0}%
+ \undochemicaloffset} % incompatible change
+ {\chemicalrotate[#2]%
+ \dochemicaloffset{#2}%
+ \def\chemicaltextelementnumber{#2}%
+ \getvalue{\s!chemicaltextelement#1}%
+ \getvalue{\s!chemicaltextelement#11}%
+ \getvalue{\s!chemicaltextelement#12}%
+ \getvalue{\s!chemicaltextelement#13}%
+ \undochemicaloffset}}
+
+\def\processchemicaltextelement#1#2#3#4#5%
+ {\def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#1#2}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#1#2}
+ {\getchemicaltextelement[#1][##1][#4][#5][#3]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {\getchemicaltextelement[#1][##1][#4][#5][#3]%
+ \doifnot{##2}{?}{\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#2]%
+ \smallchemicaltextfalse}
+
+\def\processchemicalsmalltextelement%
+ {\smallchemicaltexttrue\processchemicaltextelement}
+
+\def\processchemicalsmalltextconstant%
+ {\smallchemicaltexttrue\processchemicaltextconstant}
+
+\def\processchemicalunrotatedtextelement#1#2#3#4#5#6%
+ {\bgroup
+ \xdef\@@xxx{0}%
+ \xdef\@@yyy{0}%
+ \def\putchemicaltext##1##2%
+ {\xdef\@@xxx{##1}%
+ \xdef\@@yyy{##2}}%
+ \getvalue{\s!chemicaltextelement#1}%
+ \egroup
+ \bgroup
+ \def\doputchemicaltext##1 [##2] at ##3 ##4 %
+ {\ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\rput{\chemicalangle}(\@@xxx,\@@yyy){\expanded{\rput[##2](##3,##4){##1}}}}%
+ \else
+ \put
+ {\stoprotation \setcoordinatesystem point at 0 0
+ \expanded{\put {##1} [##2] at {##3} {##4} }}
+ at {\@@xxx} {\@@yyy}
+ \fi}%
+ \processchemicaltextelement{#2}{#3}{#4}{#5}{#6}%
+ \egroup}
+
+\newif\ifchemicaltextconstant
+
+\def\processchemicaltextconstant#1#2#3#4%
+ {\chemicaltextconstanttrue
+ \let\@@oldchemicalframe\@@chemicalframe
+ \let\@@chemicalframe\relax
+ \processchemicaltextelement{#1}{#2}{#3}{#4}{}%
+ \let\@@chemicalframe\@@oldchemicalframe
+ \chemicaltextconstantfalse}
+
+% \plotchemicalline{#1}{#2}{#3}{#4}
+%
+% #1: x-coordinaat beginpunt
+% #2: y-coordinaat beginpunt
+% #3: x-coordinaat eindpunt
+% #4: y-coordinaat eindpunt
+
+\chardef\chemicallinetype=0
+
+\def\doplotchemicalline
+ {\!!counte=\!!countc \advance\!!counte by -\!!counta
+ \!!countf=\!!countd \advance\!!countf by -\!!countb
+ \bgroup
+ \ifcase\chemicaldrawingmode
+ \ifcase\chemicallinetype
+ % 0 : normal line
+ \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /%
+ \or
+ % 1 : normal arrow
+ \arrow <5pt> [.2,.67] from {\!!counta} {\!!countb} to {\!!countc} {\!!countd}
+ \or
+ % 2 : reverse arrow
+ \arrow <5pt> [.2,.67] from {\!!countc} {\!!countd} to {\!!counta} {\!!countb}
+ \or
+ % 3 : unrotated line
+ \put {\stoprotation \setcoordinatesystem point at 0 0
+ \plot 0 0 {\!!counte} {\!!countf} /}
+ [\chemicallineposition] at {\!!counta} {\!!countb}
+ \else
+ % 4 : dashed line
+ \findlength {\plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /}%
+ \setdashesnear <2pt> for <\totalarclength>%
+ \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /%
+ \fi
+ \or
+ \ifcase\chemicallinetype
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline{->}(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline{<-}(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[\chemicallineposition]{-\chemicalangle}%
+ (\!!counta,\!!countb){\psline(0,0)(\!!counte,\!!countf)}}}%
+ \else
+ \psset{linestyle=dashed}%
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \fi
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ x3 := \MPdivten[\the\!!counte]u ;
+ y3 := \MPdivten[\the\!!countf]u ;
+ \ifcase\chemicallinetype
+ % 0 : normal line
+ draw ((z1--z2) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 1 : normal arrow
+ drawarrow ((z1--z2) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 2 : reverse arrow
+ drawarrow ((z2--z1) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 3 : unrotated line % nog \chemicalineposition: t/b
+ draw (origin--z3)
+ shifted (z1 rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \else
+ % 4 : dashed line
+ draw ((z1--z2) rotatedaround(origin,-\chemicalangle))
+% shifted z0 dashed evenly ;
+ shifted z0 dashed dashpattern(on 5.5u off 6u) ;
+ \fi
+ \stopMPdrawing
+ \fi
+ \egroup
+ \account\!!counta\!!countb
+ \account\!!countc\!!countd}
+
+\def\plotchemicalline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \doplotchemicalline}
+
+\def\plotchemicalfactorline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifdim\@@chemicalfactor\onepoint=\onepoint \else
+ \scratchdimen\!!counta\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!counta\scratchdimen
+ \scratchdimen\!!countc\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!countc\scratchdimen
+ \fi
+ \doplotchemicalline}
+
+\def\plotchemicalzline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ filldraw ((
+ \ifnum\chemicalangle>180
+ z1--z2
+ \else\ifnum\chemicalangle<90
+ z1--(z2 shifted (-2u,+2u))--(z2 shifted (+2u,-2u))
+ \else\ifnum\chemicalangle=90
+ (z1 shifted (-2u,+2u))--(z1 shifted (+2u,-2u))--
+ (z2 shifted (+2u,+2u))--(z2 shifted (-2u,-2u))
+ \else
+ (z1 shifted (+2u,+2u))--(z1 shifted (-2u,-2u))--z2
+ \fi\fi\fi
+ --cycle) rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ \stopMPdrawing
+ \else
+ \doplotchemicalline
+ \ifnum\chemicalangle>180 \else
+ \ifnum\chemicalangle=90
+ \advance\!!counta by -20 \advance\!!countc by -20
+ \doplotchemicalline
+ \advance\!!counta by 40 \advance\!!countc by 40
+ \else\ifnum\chemicalangle<90
+ \advance\!!countc by -20 \advance\!!countd by +20
+ \doplotchemicalline
+ \advance\!!countc by +40 \advance\!!countd by -40
+ \else
+ \advance\!!counta by 20 \advance\!!countb by 20
+ \doplotchemicalline
+ \advance\!!counta by -40 \advance\!!countb by -40
+ \fi\fi
+ \fi
+ \doplotchemicalline
+ \fi}
+
+\def\plotchemicaldeltaline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ filldraw ((z1--(z2 rotatedaround(z1,5))--(z2 rotatedaround(z1,-5))
+ --cycle) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\setchemicallinesegment #1 #2 #3 #4 #5
+ {\setvalue{\s!chemicallinesegment#1}{\plotchemicalline{#2}{#3}{#4}{#5}}}
+
+\def\setchemicalfactorlinesegment #1 #2 #3 #4 #5
+ {\setvalue{\s!chemicallinesegment#1}{\plotchemicalfactorline{#2}{#3}{#4}{#5}}}
+
+\def\getchemicallinesegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \dochemicaloffset{#1}%
+ \getvalue{\s!chemicallinesegment#2}%
+ \getvalue{\s!chemicallinesegment#21}%
+ \getvalue{\s!chemicallinesegment#22}%
+ \undochemicaloffset}
+
+\def\getprivatechemicallinesegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \getvalue{\s!chemicallinesegment#2#1}}
+
+\def\doprocesschemicallinesegment#1#2#3#4#5%
+ {\chardef\chemicallinetype=#1
+ \def\chemicallineposition{#2}%
+ \def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#4#5}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#4#5}
+ {#3[##1][#4]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {#3[##1][#4]%
+ \doifnot{##2}{?}
+ {\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#5]}
+
+\def\processchemicallinesegment
+ {\doprocesschemicallinesegment0c\getchemicallinesegment}
+
+\def\processchemicalzlinesegment#1#2%
+ {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \bgroup
+ \def\plotchemicalline{\plotchemicalzline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicaldeltalinesegment#1#2%
+ {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \bgroup
+ \def\plotchemicalline{\plotchemicaldeltaline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processprivatechemicallinesegment%
+ {\doprocesschemicallinesegment0c\getprivatechemicallinesegment}
+
+\def\processchemicaldownarrowsegment%
+ {\doprocesschemicallinesegment1c\getchemicallinesegment}
+
+\def\processchemicaluparrowsegment%
+ {\doprocesschemicallinesegment2c\getchemicallinesegment}
+
+\def\processchemicalunrotatedlinesegment#1%
+ {\doprocesschemicallinesegment3{#1}\getchemicallinesegment}
+
+\def\processchemicaldashedlinesegment
+ {\doprocesschemicallinesegment4c\getchemicallinesegment}
+
+\def\plotchemicaldasheddeltaline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ z20 = z2 rotatedaround(z1,+5) ;
+ z21 = z2 rotatedaround(z1,-5) ;
+ draw (z1 rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ save n ; n := 5 ;
+ for i=1 upto n :
+ draw ((((z20--z21) shifted -z2) shifted (i/n)[z2,z1])
+ rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ endfor
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\plotchemicalwavyline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ save d ; pair d ;
+ d := z2 rotatedaround(z1,+5) shifted -z2 ;
+ save n ; n := 4 ;
+ draw ((for i=0 upto n-1 :
+ ((i)/n)[z1,z2] ..
+ ((i+.25)/n)[z1,z2] shifted d ..
+ ((i+.50)/n)[z1,z2] ..
+ ((i+.75)/n)[z1,z2] shifted -d ..
+ endfor
+ z2) rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\processchemicaldasheddeltalinesegment#1#2%
+ {\bgroup
+ \def\plotchemicalline{\plotchemicaldasheddeltaline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicalwavylinesegment#1#2%
+ {\bgroup
+ \def\plotchemicalline{\plotchemicalwavyline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicalopenend#1#2%
+ {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}}
+
+\def\doprocesschemicalopenend[#1][#2]%
+ {\chemicalrotate[#1]%
+ \dochemicaloffset{#1}%
+ \ifcase\chemicaldrawingmode
+ \beginpicture
+ \setquadratic\plot
+ 300 0 400 0
+ 500 0 550 75
+ 600 0 650 -75
+ 700 0 750 75
+ 800 0 850 -75
+ 900 0 950 0
+ 1050 0 /
+ \endpicture
+ \or
+ \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(300,0)(500,0)%
+ \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}%
+ \psline(950,0)(1050,0)}%
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ draw
+ (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u)..
+ (60.0u,0)..(65.0u,-7.5u)..(70.0u,0)..
+ (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up}
+ (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \stopMPdrawing
+ \fi
+ \undochemicaloffset}
+
+% \plotchemicalcircle{#1}{#2}{#3}{#4}
+%
+% #1: lengte van de boog in graden
+% #2: x-coordinaat eindpunt
+% #3: y-coordinaat eindpunt
+
+\newif\ifchemicaldotted
+
+\def\plotchemicalcircle#1#2#3#4#5#6%
+ {\bgroup
+ \ifcase\chemicaldrawingmode
+ \ifchemicaldotted
+ \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }%
+ \divide\totalarclength by 6
+ \def\b{\the\totalarclength}%
+ \divide\totalarclength by 2
+ \def\a{\the\totalarclength}%
+ \setdashpattern <\a,\b,\b,\b,\b,\b,\a>
+ \fi
+ \circulararc {#4} degrees from {#5} {#6} center at {0} {0} %
+ \or
+ \ifchemicaldotted
+ \psset{linestyle=dashed}%
+ \fi
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psarc(0,0){#3}{#1}{#2}}%
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ r := \MPdivten[#3]*2u;
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r)))
+ rotatedaround (origin,\chemicalangle+150))
+ shifted z0 \ifchemicaldotted dashed withdots \fi ;
+ \stopMPdrawing
+ \fi
+ \egroup}
+
+\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7
+ {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}}
+
+\def\getchemicalcircsegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \getvalue{\s!chemicalcircsegment#2}}
+
+\def\doprocesschemicalcircsegment#1#2%
+ {\def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#1#2}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#1#2}
+ {\getchemicalcircsegment[##1][#1]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {\getchemicalcircsegment[##1][#1]%
+ \doifnot{##2}{?}
+ {\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#2]}
+
+\def\processchemicalcircsegment%
+ {\chemicaldottedfalse\doprocesschemicalcircsegment}
+
+\def\processchemicaldottsegment%
+ {\chemicaldottedtrue\doprocesschemicalcircsegment}
+
+\let\endchemicalpicture = \relax
+\let\checkchemicalpicture = \relax
+\let\nomoreaccounting = \relax
+
+\newif\ifchemicalpicture
+
+\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET
+ {\checkchemicalpicture
+ \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT
+ \chemicalpicturetrue
+ \processchemical[#1]}
+
+\def\setchemicalpicture#1#2%
+ {\chemicalpicturefalse
+ \def\endchemicalpicture%
+ {\@@endchemicallocalpicture{#1}{#2}%
+ \egroup
+ \ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}%
+ \else
+ \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} }
+ \fi
+ \egroup}%
+ \def\checkchemicalpicture%
+ {\ifx\endchemicalpicture\relax \else
+ \writestatus{ppchtex}{missing end of picture (PE)}%
+ \endchemicalpicture
+ \fi}%
+ \setbox\nextbox=\hbox\bgroup
+ \@@beginchemicallocalpicture
+ % alternatief: gewoon accounting, en zelf l,r afhandelen
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \accountingon
+ \let\nomoreaccounting=\accountingoff
+ \fi}
+
+\def\doskipchemical[#1][#2]%
+ {{\tt[ppchtex]}}
+
+\def\skipchemical%
+ {\dodoubleargument\doskipchemical}
+
+\def\complexchemical% met \expandafter
+ {\ifinchemical
+ \expandafter\dochemical
+ \else
+ \writestatus{ppchtex}{the [][]-alternative is not permitted here}%
+ \expandafter\skipchemical
+ \fi}
+
+\newif\ifinnerchemical
+
+\def\dosimplechemical#1#2#3%
+ {\doifdefinedelse{\??chemical\c!location}
+ {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}}
+ {\ifinnerchemical
+ \let\chemicalsign = \chemicalinnersign
+ \let\chemicalmolecule = \chemicalinnermolecule
+ \let\chemicalsinglearrow = \chemicalsingleinnerarrow
+ \let\chemicaldoublearrow = \chemicaldoubleinnerarrow
+ \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow
+ \else
+ \let\chemicalsign = \chemicaloutersign
+ \let\chemicalmolecule = \chemicaloutermolecule
+ \let\chemicalsinglearrow = \chemicalsingleouterarrow
+ \let\chemicaldoublearrow = \chemicaldoubleouterarrow
+ \let\chemicaltwintiparrow = \chemicaltwintipouterarrow
+ \fi
+ \disablechemicalspecials
+ \unexpandedprocessallactionsinset
+ [#1]
+ [ HIGH=>\sethighsubscripts,
+ LOW=>\setlowsubscripts,
+ PLUS=>\chemicalsign{+},
+ GIVES=>\chemicalsinglearrow{#2}{#3},
+ EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3},
+ MESOMERIC=>\chemicaltwintiparrow{#2}{#3},
+ SINGLE=>\singlechemicalbond,
+ DOUBLE=>\doublechemicalbond,
+ TRIPLE=>\triplechemicalbond,
+ +=>\chemicalsign{+},
+ ->=>\chemicalsinglearrow{#2}{#3},
+ <->=>\chemicaldoublearrow{#2}{#3},
+ <>=>\chemicaltwintiparrow{#2}{#3},
+ -=>\singlechemicalbond,
+ --=>\doublechemicalbond,
+ ---=>\triplechemicalbond,
+ \s!unknown=>\enablechemicalspecials
+ \chemicalmolecule{\commalistelement}{#2}{#3}]}}
+
+%\def\dosimplechemicalA#1#2#3%
+% {\let\chemicalspace=\relax
+% \def\dodosimplechemical##1%
+% {\dosimplechemical{##1}{}{}}%
+% \@EA\processcommalist\@EA[\@@chemicalchemicaloffset,#1]\dodosimplechemical
+% \egroup}
+
+\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax}
+ {\let\chemicalspace=\relax
+ \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}%
+ \egroup}
+
+\def\dosimplechemicalB#1#2#3%
+ {\dosimplechemical{#1}{#2}{#3}%
+ \egroup}
+
+\def\dosimplechemicalC#1#2#3%
+ {$\simplechemical{#1}{#2}{#3}$%
+ \egroup} % erbij
+
+\def\simplechemical
+ {\ifinner
+ \innerchemicaltrue
+ \else
+ \innerchemicalfalse
+ \fi
+ \bgroup
+ \catcode`\^=\@@superscript % t.b.v. \enableduplication
+ \catcode`\_=\@@subscript % t.b.v. de zekerheid
+ \ifmmode
+ \ifinnerchemical
+ \def\next{\dotriplegroupempty\dosimplechemicalA}%
+ \else
+ \def\next{\dotriplegroupempty\dosimplechemicalB}%
+ \fi
+ \else
+ \def\next{\dotriplegroupempty\dosimplechemicalC}%
+ \fi
+ \next}
+
+\definecomplexorsimple\chemical
+
+\def\dogotochemical#1#2%
+ {\def\dowithchemical% % experiment
+ {\localgotochemical{#1}}% % experiment
+ \chemical} % experiment
+
+\def\gotochemical% % experiment
+ {\dosingleargument\dogotochemical} % experiment
+
+\def\dododochemical#1[#2][#3]% % experiment
+ {\def\simpledododochemical% % experiment
+ {#1[#2][#3]}% % experiment
+ \def\complexdododochemical[##1]% % experiment
+ {\def\dowithchemical% % experiment
+ {\localthisischemical{#2}}% % experiment
+ #1[#3][##1]}% % experiment
+ \complexorsimple\dododochemical} % experiment
+
+\def\dodochemical[#1][#2]%
+ {\ignorespaces
+ \ifinchemical
+ \drawchemical[#1][#2]%
+ \ignorespaces
+ \else
+ \startchemical[\c!location=\v!intext]%
+ \drawchemical[#1][#2]%
+ \expandafter\stopchemical
+ \fi
+ \ignorespaces}
+
+\def\dochemical[#1]%
+ {\def\simpledochemical%
+ {\@@writechemicalstate{ppchtex}{[#1][]}%
+ \dodochemical[#1][]}%
+ %
+ \def\complexdochemical[##1]%
+ {\@@writechemicalstate{ppchtex}{[#1][##1]}%
+ \txtchemical=0%
+ \dodochemical[#1][##1]}%
+ %
+ \def\complexdochemical[##1]% % experiment
+ {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment
+ \txtchemical=0% % experiment
+ \dododochemical\dodochemical[#1][##1]}% % experiment
+ %
+ \complexorsimple\dochemical}
+
+% \processlocalchemicals{#1}
+%
+% #1: commando's
+
+\def\dodoprocesschemical#1%
+ {\processchemical[#1????]}
+
+\def\processlocalchemicals#1%
+ {\processcommalist[#1]\dodoprocesschemical}
+
+% \drawchemical[#1][#2]
+%
+% #1: bindingen enz.
+% #2: atomen enz.
+
+\def\localdodochemical[#1][#2]%
+ {\@@writechemicalstate{ppchtex}{[#1][#2]}%
+ %\bgroup % koppelen en afmetingen gaat fout, vandaar:
+ \advance\levchemical 1
+ \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical
+ \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}%
+ \txtchemical=0
+ \dodochemical[#1][#2]%
+ % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname
+ \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname
+ \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname
+ \advance\levchemical -1
+ %\egroup
+ \ignorespaces}
+
+\def\drawchemical[#1][#2]%
+ {\ignorespaces
+ \def\dodochemical[##1][##2]%
+ {\drawchemical[##1][##2]%
+ \ignorespaces}%
+ \def\dochemical[##1]%
+ {\def\simpledochemical%
+ {\@@writechemicalstate{ppchtex}{[##1][#2]}%
+ \dodochemical[##1][#2]%
+ \ignorespaces}%
+ \def\complexdochemical[####1]%
+ {\dododochemical\localdodochemical[##1][####1,#2]}%
+ \complexorsimple\dochemical}%
+ \doif\@@chemicalstate\v!start
+ {\doifelse\chemicalname\s!unknown
+ {\getvalue{\s!executechemical\defaultchemical}[#2]}
+ {\getvalue{\s!executechemical\chemicalname}[#2]}%
+ \def\unknownchemical##1%
+ {\processunknownchemical[##1][#2]}%
+ \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}%
+ \ignorespaces}
+
+\unexpanded\def\chemicaloxidation#1#2#3%
+ {\chemicaltop
+ {\ifnum#20=0
+ 0%
+ \else
+ #1\expandafter\uppercase\expandafter{\romannumeral#2}%
+ \fi}
+ {#3}}
+
+\def\chemicaltfraction{\ifinchemical.60\else.8\fi}
+\def\chemicalbfraction{\ifinchemical.45\else.6\fi}
+\def\chemicallfraction{\ifinchemical.1\else.1\fi}
+\def\chemicalrfraction{\ifinchemical.1\else.1\fi}
+
+\def\chemicaltighttext
+ {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}%
+ \def\chemicalbfraction{\ifinchemical.2\else.4\fi}%
+ \def\chemicallfraction{\ifinchemical 0\else 0\fi}%
+ \def\chemicalrfraction{\ifinchemical 0\else 0\fi}}
+
+\def\dochemicaltop#1#2#3#4%
+ {\vbox
+ {\@@dochemicalcolor
+ \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt
+ \halign
+ {#1###2\cr
+ $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr
+ $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}}
+
+\def\dochemicalbottom#1#2#3#4%
+ {\vtop
+ {\@@dochemicalcolor
+ \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt
+ \halign
+ {#1###2\cr
+ $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr
+ $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}}
+
+\def\chemicalleft#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\scriptscriptstyle#1}$%
+ $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}}
+
+\def\chemicalright#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$%
+ $\@@dochemicalstyle{\scriptscriptstyle#1}$}}
+
+\def\chemicalcentered#1%
+ {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \dimen0=.5\ht2
+ \advance\dimen0 by -.5\ht0
+ \advance\dimen0 by \dp0
+ \hbox{\@@dochemicalcolor\raise\dimen0\box0}}
+
+\def\chemicalleftcentered#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ \chemicalcentered{#1}%
+ $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}}
+
+\def\chemicalrightcentered#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$%
+ \chemicalcentered{#1}}}
+
+\def\chemicaltop {\dochemicaltop \hss \hss }
+\def\chemicallefttop {\dochemicaltop \relax \hss }
+\def\chemicalrighttop {\dochemicaltop \hss \relax}
+\def\chemicalbottom {\dochemicalbottom \hss \hss }
+\def\chemicalleftbottom {\dochemicalbottom \relax \hss }
+\def\chemicalrightbottom {\dochemicalbottom \hss \relax}
+
+\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}}
+\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}}
+\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}}
+\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}}
+
+\def\chemicalsmashedleft#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \wd2=\wd0
+ \box2
+ \egroup}
+
+\def\chemicalsmashedmiddle#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \hbox{\hskip-.5\wd2\hskip.5\wd0\box2}
+ \egroup}
+
+\def\chemicalsmashedright#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}%
+ \egroup}
+
+\def\+{\tabalign} % is \long in Plain
+
+\def\chemicalforever#1#2%
+ {\bgroup
+ \setbox0=\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}%
+ \wd0=0pt
+ \big#1_{\hskip.1em\box0}%
+ \egroup}
+
+\def\disablechemicalspecials%
+ {\def\+##1{##1}\def\-##1{##1}%
+ \def\[{[}\def\]{]}%
+ \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}%
+ \def\X{}%
+ \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}%
+ \def\TL{}\def\BL{}\def\TR{}\def\BR{}%
+ \def\LT{}\def\LB{}\def\RT{}\def\RB{}%
+ \def\SL{}\def\SM{}\def\SR{}}
+
+\def\enablechemicalspecials%
+ {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed!
+ \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed!
+ \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed!
+ \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed!
+ \def\1{\chemicaloxidation\relax1}%
+ \def\2{\chemicaloxidation\relax2}%
+ \def\3{\chemicaloxidation\relax3}%
+ \def\4{\chemicaloxidation\relax4}%
+ \def\5{\chemicaloxidation\relax5}%
+ \def\6{\chemicaloxidation\relax6}%
+ \def\7{\chemicaloxidation\relax7}%
+ \def\X{\chemicaltighttext}%
+ \def\T{\chemicaltop}%
+ \def\B{\chemicalbottom}%
+ \def\L{\chemicalleft}%
+ \def\LC{\chemicalleftcentered}%
+ \def\R{\chemicalright}%
+ \def\RC{\chemicalrightcentered}%
+ \def\TL{\chemicaltopleft}%
+ \def\BL{\chemicalbottomleft}%
+ \def\TR{\chemicaltopright}%
+ \def\BR{\chemicalbottomright}%
+ \def\LT{\chemicallefttop}%
+ \def\LB{\chemicalleftbottom}%
+ \def\RT{\chemicalrighttop}%
+ \def\RB{\chemicalrightbottom}%
+ \def\SL{\chemicalsmashedleft}%
+ \def\SM{\chemicalsmashedmiddle}%
+ \def\SR{\chemicalsmashedright}%
+}
+
+% \reversechemical#1#2#3
+%
+% #1: prefix
+% #2: volgnummer enz
+% #3: tegengestelde volgnummers
+
+\def\reversechemical#1#2#3%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{#1#2}%
+ {\getfromcommalist[#3][##1]%
+ \let\reversechemicalaction=\commalistelement
+ \processchemical[#1\reversechemicalaction##2]}}%
+ \doprocess[#2]}
+
+% \processunknownchemical[#1????][#2]
+%
+% #1: bindingen enz.
+% #2: atomen enz.
+
+\def\defaultchemical%
+ {SIX}
+
+\def\processunknownchemical[#1????][#2]%
+ {\processaction
+ [#1]
+ [ SAVE=>\executechemicalSAVE,
+ RESTORE=>\executechemicalRESTORE,
+ HIGH=>\sethighsubscripts,
+ LOW=>\setlowsubscripts,
+ \s!default=>,
+ \s!unknown=>\doifdefinedelse{\s!executechemical#1}
+ {\def\chemicalrotation{1}%
+ \def\chemicaloffset{0}%
+ \doifdefined{\s!executechemical#1}
+ {\getvalue{\s!executechemical#1}[#2]}%
+ \@@chemicalpostponed}
+ {\getpredefinedchemical{#1}}]}
+
+\newcount\chemicalstack % tzt \newwounter
+
+\setvalue{\s!chemical\c!x1}{0}
+\setvalue{\s!chemical\c!y1}{0}
+
+\def\executechemicalSAVE
+ {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}%
+ \advance\chemicalstack by 1
+ \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname
+ %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed
+ \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}%
+ \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}}
+
+\def\restorechemicalvalues#1%
+ {\let\oldprocesschemical=\processchemical
+ \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}%
+ \let\processchemical=\oldprocesschemical}
+
+\def\executechemicalRESTORE
+ {\ifnum\chemicalstack=0\relax
+ \horchemical=\getvalue{\s!chemical x1}\relax
+ \verchemical=\getvalue{\s!chemical y1}\relax
+ \else
+ \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}%
+ %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname
+ \let\@@chemicalpostponed=\relax
+ \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax
+ \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax
+ \advance\chemicalstack by -1
+ \fi
+ \restorechemicalcoordinates}
+
+% De onderstaande macro's zijn verantwoordelijk voor het zetten
+% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog
+% gehaald. Dit oogt m.i. fraaier.
+
+\def\chemicalinnerclip#1%
+ {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}}
+
+\def\chemicalraise#1#2%
+ {\chemicalinnerclip
+ {\setbox0=\hbox{$#1+$}%
+ \raise\dp0\hbox{$#1#2$}}}
+
+\def\chemicalinnersign#1% todo: \@@chemicaltextcolor
+ {\chemicalraise{\@@localchemicalstyle}{#1}}
+
+\def\chemicaloutersign#1%
+ {\chemicalraise{}{\@@dochemicalcolor#1}}
+
+\def\chemicalsingleinnerarrow#1#2%
+ {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}
+
+\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor
+ {\chemicalinnerclip
+ {\lower.2ex\hbox
+ {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}%
+ \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}%
+ \wd0=0pt\raise\ht0\box0\box2}}}
+
+\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor
+ {\chemicalinnerclip
+ {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}%
+ \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}%
+ \wd0=0pt\box0\box2}}
+
+\def\dochemicalouterarrow#1#2#3%
+ {\bgroup
+ \setbox0=\hbox{$\longrightarrow$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}%
+ \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}%
+ \dimen2=\wd0 % \dimen0 is used elsewhere
+ \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi
+ \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi
+ \chemicaloutermolecule
+ {#1}
+ {\ifdim\ht2>\!!zeropoint\box2\fi} % expands to \empty in test
+ {\ifdim\ht4>\!!zeropoint\box4\fi}% % expands to \empty in test
+ \egroup}
+
+\def\chemicalsingleouterarrow
+ {\dochemicalouterarrow
+ {\hbox to \dimen2{\rightarrowfill}}}
+
+\def\chemicaldoubleouterarrow
+ {\dochemicalouterarrow
+ {\lower.5\ht0\vbox
+ {\offinterlineskip
+ \hbox to \dimen2{\rightarrowfill}
+ \hbox to \dimen2{\leftarrowfill}}}}
+
+\def\chemicaltwintipouterarrow
+ {\dochemicalouterarrow
+ {\hbox
+ {\hbox to \dimen2{\rightarrowfill}%
+ \hskip-\dimen2
+ \hbox to \dimen2{\leftarrowfill}}}}
+
+\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space
+ {\chemicalspace % todo: \@@chemicaltextcolor
+ \chemicalinnerclip
+ {\dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$%
+ \doresetsubscripts}%
+ \chemicalspace}
+
+\def\chemicaloutermolecule#1#2#3%
+ {\chemicalspace
+ \bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox % else the font is reset
+ {\dosetsubscripts
+ \hbox{$\@@dochemicalstyle{\strut#1}$}%
+ \doresetsubscripts}%
+ \mathop{\box0}%
+ \ifthirdargument
+ \doifnot{#2}{}
+ {^{\@@dochemicalstyle{\strut#2}}}%
+ \doifnot{#3}{}
+ {_{\@@dochemicalstyle{\strut#3}}}%
+ \else
+ \doifnot{#2}{}
+ {_{\@@dochemicalstyle{\strut#2}}}%
+ \fi
+ \egroup
+ \chemicalspace}
+
+\def\chemicalsinglepicturearrow#1%
+ {\lower.5ex\hbox
+ {\@@dochemicalstyle
+ $\chemicalspace
+ \buildrel
+ \@@dochemicalstyle{\scriptstyle\quad#1\quad}%
+ \over{\overrightarrow
+ {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}%
+ \chemicalspace$}}
+
+\def\chemicaldoublepicturearrow#1%
+ {\lower.5ex\hbox
+ {\@@dochemicalstyle
+ $\chemicalspace
+ \buildrel
+ \@@dochemicalstyle{\scriptstyle\quad#1\quad}%
+ \over{\overrightarrow{\overleftarrow
+ {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}%
+ \chemicalspace$}}
+
+% Bij de in-line bindingen wordt gebruik gemaakt van
+% een \hrule. De maatvoering wordt bepaald door een
+% kunstmatige em (\wd0).
+
+\def\somechemicalbond%
+ {\hrule width \wd0 height .4pt}
+
+\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle
+ {{\setbox0=\hbox
+ {${\@@localchemicalstyle M}$}%
+ \vbox to \ht0
+ {\@@dochemicalcolor
+ \hsize\wd0
+ \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}}
+
+\def\singlechemicalbond%
+ {\dochemicalbonds{}{\somechemicalbond}{}}
+
+\def\doublechemicalbond%
+ {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}}
+
+\def\triplechemicalbond%
+ {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}}
+
+% In plaats van \def\naam{\chemie[...]...} kan beter gebruik
+% worden gemaakt van het commando
+%
+% \definieerchemie[naam]{commando's}
+%
+% De naam krijgt, om problemen met bestaande macro's te
+% voorkomen, een prefix. Bij het ophalen van een commando
+% worden beide definities afgehandeld.
+
+\def\dodefinechemical[#1]#2%
+ {\doifdefined{\??chemical#1}
+ {\writestatus{ppchtex}{chemical definition #1 is redefined}}%
+ \setvalue{\??chemical#1}{#2}}
+
+\def\definechemical%
+ {\dosingleargument\dodefinechemical}
+
+\def\getpredefinedchemical#1%
+ {\doifdefinedelse{\??chemical#1}
+ {\getvalue{\??chemical#1}}
+ {\doifdefinedelse{#1}
+ {\getvalue{#1}}
+ {\writestatus{ppchtex}{unknown chemical definition #1}}}}
+
+% Hieronder zijn de definities van de structuren opgenomen. De
+% naam van de structuur is als volgt opgebouwd:
+%
+% \executechemicalNUMBER[#1]
+%
+% waarbij [#1] betrekking heeft op de tekstelementen van \chemie,
+% de [tweede lijst] dus.
+%
+% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt
+% deels door de in \execute gedefinieerde macro's afgehandeld,
+% deels door algemene macro's. Segmenten hebben de vorm:
+%
+% [+|-|]identifier[X|XYZ|X..Y]
+%
+% Voorbeelden van segmenten zijn:
+%
+% R1
+% R1..4
+% R135
+% -R1
+% +R35
+
+\setchemicalmaximum 0
+
+\def\processchemical[#1]%
+ {\unknownchemical{#1}}
+
+\def\setchemicalname#1 %
+ {\def\chemicalname{#1}}
+
+\let\chemicalname=\s!unknown
+
+% Vooruitlopend op een gedetailleerde documentatie, zijn hier
+% vast enkele gebruikte afmetingen:
+%
+% lengte radikalen : 500
+% afstand radikalen : 100
+% afstand dubbele radikalen : 260
+% afstand substituenten : +125
+
+\def\executechemicalONE[#1]%
+ {\setchemicalname ONE
+ %
+ \setchemicalmaximum 8
+ \setchemicaldistance 0
+ \setchemicalsubstitute 625
+ \setchemicaldirection 303
+ %
+ \setchemicalrotation 1 1 0 1 0 1 0 1 0
+ \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707
+ \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1
+ \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707
+ \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0
+ \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707
+ \setchemicalrotation 7 0 1 0 1 0 1 0 1
+ \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 45 135 225 315
+ \setchemicalangle 3 90 180 270 0
+ \setchemicalangle 4 135 225 315 45
+ \setchemicalangle 5 180 270 0 90
+ \setchemicalangle 6 225 315 45 135
+ \setchemicalangle 7 270 0 90 180
+ \setchemicalangle 8 315 45 135 225
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 -1000 1000
+ \setchemicaltranslate 3 0 1000
+ \setchemicaltranslate 4 1000 1000
+ \setchemicaltranslate 5 1000 0
+ \setchemicaltranslate 6 1000 -1000
+ \setchemicaltranslate 7 0 -1000
+ \setchemicaltranslate 8 -1000 -1000
+ %
+ \setchemicallinesegment SB 300 0 700 0
+ \setchemicallinesegment DB1 300 50 700 50
+ \setchemicallinesegment DB2 300 -50 700 -50
+ %
+ %setchemicallinesegment EP 200 125 200 -125
+ \setchemicalfactorlinesegment EP 200 125 200 -125
+ %
+ \setchemicaltextelement ES 200 0
+ \setchemicaltextelement ED1 200 50
+ \setchemicaltextelement ED2 200 -50
+ \setchemicaltextelement ET1 200 75
+ \setchemicaltextelement ET2 200 0
+ \setchemicaltextelement ET3 200 -75
+ \setchemicaltextelement HB1 300 0
+ \setchemicaltextelement HB2 475 0
+ \setchemicaltextelement HB3 650 0
+ %
+ \setchemicaltextelement Z 800 0
+ \setchemicaltextelement RZ 950 0
+ \setchemicaltextelement ZN 500 0
+ \setchemicaltextelement ZTN 500 150
+ \setchemicaltextelement ZBN 500 -150
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\doprocesschemical[##1##2##3##4##5]
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ DIR##4##5=>\processchemicaldirection{##4##5},
+ OFF##4##5=>\processchemicaloffset{##4##5},
+ CCD##4##5=>\processchemicaldottsegment{CC}{##4##5},
+ LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}%
+ \processchemicallinesegment{DB2}{##4##5},
+ RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}%
+ \processchemicaldashedlinesegment{DB2}{##4##5},
+ OF##3:##5=>\processchemicalphantom{##3}{##5},
+ OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5},
+ EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5},
+ ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0},
+ ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0},
+ ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0},
+ HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5},
+ BD##3##4##5=>\processchemicaldasheddeltalinesegment{SB}{##3##4##5},
+ BW##3##4##5=>\processchemicalwavylinesegment{SB}{##3##4##5},
+ SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5},
+ TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}%
+ \processchemicallinesegment{DB}{##3##4##5},
+ CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{},
+ ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0},
+ ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{},
+ ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0},
+ ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{},
+ ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0},
+ ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}
+ {l,l,t,r,r,r,b,l},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}}
+
+\def\executechemicalTHREE[#1]%
+ {\setchemicalname THREE
+ %
+ \setchemicalmaximum 3
+ \setchemicaldistance 289
+ \setchemicalsubstitute 952
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5
+ \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 120 210 300 30
+ \setchemicalangle 3 240 330 60 150
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 0 1000
+ \setchemicaltranslate 3 1000 0
+ \setchemicaltranslate 4 0 -1000
+ %
+ \setchemicallinesegment B 577 0 -289 -500
+ \setchemicallinesegment SB 352 -130 -64 -370
+ \setchemicallinesegment -SB 352 -130 -289 -500
+ \setchemicallinesegment +SB 577 0 -64 -370
+ \setchemicallinesegment DB1 327 -87 -89 -327
+ \setchemicallinesegment DB2 377 -172 -39 -413
+ \setchemicallinesegment R 577 0 1077 0
+ \setchemicallinesegment -R 577 0 1010 250
+ \setchemicallinesegment +R 577 0 1010 -250
+ \setchemicallinesegment ER1 577 50 1077 50
+ \setchemicallinesegment ER2 577 -50 1077 -50
+ \setchemicallinesegment SR 837 0 1077 0
+ \setchemicallinesegment -SR 802 130 1010 250
+ \setchemicallinesegment +SR 802 -130 1010 -250
+ \setchemicallinesegment DR1 837 50 1077 50
+ \setchemicallinesegment DR2 837 -50 1077 -50
+ %
+ \setchemicaltextelement Z 577 0
+ \setchemicaltextelement RZ 1177 0
+ \setchemicaltextelement -RZ 1097 300
+ \setchemicaltextelement +RZ 1097 -300
+ \setchemicaltextelement CRZ 1077 0
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ ROT##4=>\processchemicalrotation{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3}
+ {l,t,r, l,r,l, r,b,l, r,l,r},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3}
+ {l,r,b, r,r,l, r,l,t, l,l,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}
+ {},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3}
+ {l,r,r, t,r,l, r,l,l, b,l,r},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalFOUR[#1]%
+ {\setchemicalname FOUR
+ %
+ \setchemicalmaximum 4
+ \setchemicaldistance 500
+ \setchemicalsubstitute 0
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0 -1 -1 0 0 1 1 0
+ \setchemicalrotation 3 -1 0 0 1 1 0 0 -1
+ \setchemicalrotation 4 0 1 1 0 0 -1 -1 0
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 90 180 270 0
+ \setchemicalangle 3 180 270 0 90
+ \setchemicalangle 4 270 0 90 180
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 0 1000
+ \setchemicaltranslate 3 1000 0
+ \setchemicaltranslate 4 0 -1000
+ %
+ \setchemicallinesegment B 500 500 500 -500
+ \setchemicallinesegment SB 500 240 500 -240
+ \setchemicallinesegment -SB 500 240 500 -500
+ \setchemicallinesegment +SB 500 500 500 -240
+ \setchemicallinesegment DB1 450 240 450 -240
+ \setchemicallinesegment DB2 550 240 550 -240
+ \setchemicallinesegment EB 360 300 360 -300
+ \setchemicallinesegment R 500 500 854 854
+ \setchemicallinesegment -R 500 500 500 1000
+ \setchemicallinesegment +R 500 500 1000 500
+ \setchemicallinesegment ER1 465 535 819 889
+ \setchemicallinesegment ER2 535 465 889 819
+ \setchemicallinesegment SR 684 684 854 854
+ \setchemicallinesegment -SR 500 760 500 1000
+ \setchemicallinesegment +SR 760 500 1000 500
+ \setchemicallinesegment DR1 649 719 819 889
+ \setchemicallinesegment DR2 719 649 889 819
+ %
+ \setchemicaltextelement Z 500 500
+ \setchemicaltextelement RZ 925 925
+ \setchemicaltextelement -RZ 500 1100
+ \setchemicaltextelement +RZ 1100 500
+ \setchemicaltextelement CRZ 1038 1038
+ %
+ \setchemicaltextelement ZN 350 350
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ PB:##4=>\beginchemicalpicture{##4},
+ PE????=>\endchemicalpicture,
+ ROT##4=>\processchemicalrotation{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4}
+ {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4}
+ {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{},
+ ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0},
+ ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ EB##3##4=>\processchemicallinesegment{EB}{##3##4},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4}
+ {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalFIVE[#1]%
+ {\setchemicalname FIVE
+ %
+ \setchemicalmaximum 5
+ \setchemicaldistance 688
+ \setchemicalsubstitute 1226
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309
+ \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809
+ \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809
+ \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 72 162 252 342
+ \setchemicalangle 3 144 234 324 54
+ \setchemicalangle 4 216 306 36 126
+ \setchemicalangle 5 288 18 108 198
+ %
+ \setchemicaltranslate 1 -1376 0
+ \setchemicaltranslate 2 -425 1304
+ \setchemicaltranslate 3 1113 809
+ \setchemicaltranslate 4 1113 -809
+ \setchemicaltranslate 5 -425 -1304
+ %
+ \setchemicallinesegment A 1188 500 1188 -500
+ \setchemicallinesegment B 688 500 688 -500
+ \setchemicallinesegment S -263 808 688 -500
+ \setchemicallinesegment SS -116 606 541 -298
+ \setchemicallinesegment -SS -263 808 541 -298
+ \setchemicallinesegment +SS -116 606 688 -500
+ \setchemicallinesegment SB 688 240 688 -240
+ \setchemicallinesegment -SB 688 240 688 -500
+ \setchemicallinesegment +SB 688 500 688 -240
+ \setchemicallinesegment DB1 638 240 638 -240
+ \setchemicallinesegment DB2 738 240 738 -240
+ \setchemicallinesegment EB 548 340 548 -340
+ \setchemicallinesegment R 688 500 1093 794
+ \setchemicallinesegment -R 688 500 688 1000
+ \setchemicallinesegment +R 688 500 1163 345
+ \setchemicallinesegment ER1 659 540 1064 834
+ \setchemicallinesegment ER2 727 460 1122 754
+ \setchemicallinesegment SR 898 653 1093 794
+ \setchemicallinesegment -SR 688 760 688 1000
+ \setchemicallinesegment +SR 935 420 1163 345
+ \setchemicallinesegment DR1 869 693 1064 834
+ \setchemicallinesegment DR2 927 613 1122 754
+ %
+ \setchemicaltextelement Z 688 500
+ \setchemicaltextelement RZ 1188 863
+ \setchemicaltextelement -RZ 688 1100
+ \setchemicaltextelement +RZ 1258 315
+ \setchemicaltextelement CRZ 1323 947
+ %
+ \setchemicalcircsegment C -36 36 590 72 475 -345
+ \setchemicalcircsegment CC -72 0 590 72 182 -561
+ %
+ \setchemicaltextelement ZN 468 350
+ \setchemicaltextelement RN 860 625 % 1.25 Z
+ \setchemicaltextelement RTN 785 728 % .12 / 103 75
+ \setchemicaltextelement RBN 935 522
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ FRONT????=>{\executechemicalFIVEFRONT[#1]},
+ PB:##4=>\beginchemicalpicture{##4},
+ PE????=>\endchemicalpicture,
+ ROT##4=>\processchemicalrotation{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5}
+ {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5}
+ {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ -RD##4=>\processchemicaldashedlinesegment{-R}{##4},
+ +RD##4=>\processchemicaldashedlinesegment{+R}{##4},
+ -RB##4=>\processchemicaldeltalinesegment{-R}{##4},
+ +RB##4=>\processchemicaldeltalinesegment{+R}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{},
+ RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0},
+ RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{},
+ RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0},
+ RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{},
+ -SS##4=>\processchemicallinesegment{-SS}{##4},
+ +SS##4=>\processchemicallinesegment{+SS}{##4},
+ CCD##4=>\processchemicaldottsegment{CC}{##4},
+ SS##3##4=>\processchemicallinesegment{SS}{##3##4},
+ RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4},
+ RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4},
+ ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0},
+ ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{},
+ RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0},
+ RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{},
+ AU##3##4=>\processchemicaluparrowsegment{A}{##3##4},
+ AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4},
+ CC##3##4=>\processchemicalcircsegment{CC}{##3##4},
+ CD##3##4=>\processchemicaldottsegment{C}{##3##4},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ EB##3##4=>\processchemicallinesegment{EB}{##3##4},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5}
+ {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ S##2##3##4=>\processchemicallinesegment{S}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalSIX[#1]%
+ {\setchemicalname SIX
+ %
+ \setchemicalmaximum 6
+ \setchemicalsubstitute 1375
+ \setchemicaldistance 866
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5
+ \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5
+ \setchemicalrotation 4 -1 0 0 1 1 0 0 -1
+ \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5
+ \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 60 150 240 330
+ \setchemicalangle 3 120 210 300 30
+ \setchemicalangle 4 180 270 0 90
+ \setchemicalangle 5 240 330 60 150
+ \setchemicalangle 6 300 30 120 210
+ %
+ \setchemicaltranslate 1 -1732 0
+ \setchemicaltranslate 2 -866 1500
+ \setchemicaltranslate 3 866 1500
+ \setchemicaltranslate 4 1732 0
+ \setchemicaltranslate 5 866 -1500
+ \setchemicaltranslate 6 -866 -1500
+ %
+ \setchemicallinesegment A 1386 500 1386 -500
+ \setchemicallinesegment S 0 1000 866 -500
+ \setchemicallinesegment SS 125 783 741 -283
+ \setchemicallinesegment -SS 0 1000 741 -283
+ \setchemicallinesegment +SS 125 783 866 -500
+ \setchemicallinesegment B 866 500 866 -500
+ \setchemicallinesegment SB 866 240 866 -240
+ \setchemicallinesegment -SB 866 240 866 -500
+ \setchemicallinesegment +SB 866 500 866 -240
+ \setchemicallinesegment DB1 816 240 816 -240
+ \setchemicallinesegment DB2 916 240 916 -240
+ \setchemicallinesegment EB 726 340 726 -340
+ \setchemicallinesegment R 866 500 1299 750
+ \setchemicallinesegment -R 866 500 866 1000
+ \setchemicallinesegment +R 866 500 1299 250
+ \setchemicallinesegment ER1 841 543 1274 793
+ \setchemicallinesegment ER2 891 457 1324 707
+ \setchemicallinesegment SR 1091 630 1299 750
+ \setchemicallinesegment -SR 866 740 866 1000
+ \setchemicallinesegment +SR 1091 370 1299 250
+ \setchemicallinesegment DR1 1066 673 1274 793
+ \setchemicallinesegment DR2 1116 588 1324 707
+ \setchemicallinesegment MID1 0 1000 -150 200
+ \setchemicallinesegment MID2 0 -1000 -150 -200
+ \setchemicallinesegment MIDS1 0 1000 -180 0
+ \setchemicallinesegment MIDS2 0 -1000 -180 0
+ %
+ \setchemicalcircsegment C -30 30 700 60 600 -346
+ \setchemicalcircsegment CC -60 0 700 60 350 -606
+ %
+ \setchemicaltextelement Z 866 500
+ \setchemicaltextelement RZ 1386 800
+ \setchemicaltextelement -RZ 866 1100
+ \setchemicaltextelement +RZ 1386 200
+ \setchemicaltextelement CRZ 1524 880
+ \setchemicaltextelement MIDZ -150 0
+ %
+ \setchemicaltextelement ZN 589 350
+ \setchemicaltextelement RN 1083 625 % 1.25 Z
+ \setchemicaltextelement RTN 1008 755 % .12 / 130 75
+ \setchemicaltextelement RBN 1158 495
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ FRONT????=>{\executechemicalSIXFRONT[#1]},
+ MID????=>\processchemicallinesegment{MID}{1????},
+ MIDS????=>\processchemicallinesegment{MIDS}{1????},
+ MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{},
+ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ ROT##4##5=>\processchemicalrotation{##4##5},
+ SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6}
+ {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r},
+ +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6}
+ {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ -SR##4##5=>\processchemicallinesegment{-SR}{##4##5},
+ +SR##4##5=>\processchemicallinesegment{+SR}{##4##5},
+ -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5},
+ +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5},
+ -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5},
+ +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5},
+ CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{},
+ -SS##4##5=>\processchemicallinesegment{-SS}{##4##5},
+ +SS##4##5=>\processchemicallinesegment{+SS}{##4##5},
+ CCD##4##5=>\processchemicaldottsegment{CC}{##4##5},
+RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0},
+RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{},
+RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0},
+RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{},
+ SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5},
+ RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5},
+ RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5},
+ ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0},
+ ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{},
+RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0},
+RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{},
+ AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5},
+ AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5},
+ CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5},
+ CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5},
+ DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5},
+ EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5},
+ ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5},
+ RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6}
+ {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5},
+ DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5},
+ -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5},
+ +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5},
+ R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5},
+ S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalSEVEN[#1]% incomplete !
+ {\setchemicalname SEVEN
+ %
+ \setchemicalmaximum 7
+ \setchemicalsubstitute -
+ \setchemicaldistance 1038
+ %
+ \setchemicalrotation 1 .623 .782 - - - - - -
+ \setchemicalrotation 2 -.223 .975 - - - - - -
+ \setchemicalrotation 3 -.901 .434 - - - - - -
+ \setchemicalrotation 4 -.901 -.434 - - - - - -
+ \setchemicalrotation 5 -.223 -.975 - - - - - -
+ \setchemicalrotation 6 .623 -.782 - - - - - -
+ \setchemicalrotation 7 1 0 - - - - - -
+ %
+ \setchemicalangle 1 0 - - -
+ \setchemicalangle 2 51.429 - - -
+ \setchemicalangle 3 102.857 - - -
+ \setchemicalangle 4 154.286 - - -
+ \setchemicalangle 5 205.714 - - -
+ \setchemicalangle 6 257.143 - - -
+ \setchemicalangle 7 308.571 - - -
+ %
+ \setchemicaltranslate 1 - -
+ \setchemicaltranslate 2 - -
+ \setchemicaltranslate 3 - -
+ \setchemicaltranslate 4 - -
+ \setchemicaltranslate 5 - -
+ \setchemicaltranslate 6 - -
+ \setchemicaltranslate 7 - -
+ %
+ \setchemicallinesegment B 1038 500 1038 -500
+ \setchemicallinesegment SB 1038 240 1038 -240
+ \setchemicallinesegment -SB 1038 240 1038 -500
+ \setchemicallinesegment +SB 1038 500 1038 -240
+ %
+ \setchemicaltextelement Z 1038 500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ %ROT##4##5=>\processchemicalrotation{##4},
+ %SUB##4##5=>\processchemicalsubstitute{##4##5},
+ %ADJ##4##5=>\processchemicaldistance{##4##5},
+ %MOV##4##5=>\processchemicaltranslate{##4##5},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalEIGHT[#1]% incomplete !
+ {\setchemicalname EIGHT
+ %
+ \setchemicalmaximum 8
+ %\setchemicalsubstitute 1307
+ \setchemicaldistance 1207
+ %
+ \setchemicalrotation 1 .707 .707 - - - - - -
+ \setchemicalrotation 2 0 1 - - - - - -
+ \setchemicalrotation 3 -.707 .707 - - - - - -
+ \setchemicalrotation 4 -1 0 - - - - - -
+ \setchemicalrotation 5 -.707 -.707 - - - - - -
+ \setchemicalrotation 6 0 -1 - - - - - -
+ \setchemicalrotation 7 .707 -.707 - - - - - -
+ \setchemicalrotation 8 1 0 - - - - - -
+ %
+ \setchemicalangle 1 45 - - -
+ \setchemicalangle 2 90 - - -
+ \setchemicalangle 3 135 - - -
+ \setchemicalangle 4 180 - - -
+ \setchemicalangle 5 225 - - -
+ \setchemicalangle 6 270 - - -
+ \setchemicalangle 7 315 - - -
+ \setchemicalangle 8 0 - - -
+ %
+ \setchemicaltranslate 1 -2414 0
+ \setchemicaltranslate 2 -1706 1706
+ \setchemicaltranslate 3 0 2414
+ \setchemicaltranslate 4 1706 1706
+ \setchemicaltranslate 5 2414 0
+ \setchemicaltranslate 6 1706 -1706
+ \setchemicaltranslate 7 0 -2414
+ \setchemicaltranslate 8 -1706 -1706
+ %
+ \setchemicallinesegment B 1207 500 1207 -500
+ \setchemicallinesegment SB 1207 240 1207 -240
+ \setchemicallinesegment -SB 1207 240 1207 -500
+ \setchemicallinesegment +SB 1207 500 1207 -240
+ %
+ \setchemicaltextelement Z 1207 500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ %SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalFIVEFRONT[#1]%
+ {\executechemicalFIVE[]%
+ %
+ \setchemicalname FIVEFRONT
+ %
+ \setchemicallinesegment -R 688 500 688 100
+ \setchemicallinesegment +R 688 500 688 900
+ %
+ \setchemicaltextelement -RZ 0 -1300
+ \setchemicaltextelement +RZ 0 1300
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\def\chemicalrotation{2}%
+ \processaction
+ [##1##2##3##4]
+ [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5}
+ {,,,,, t,t,t,t,t},
+ +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5}
+ {,,,,, b,b,b,b,b},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4},
+ +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4},
+ BB##3##4=>\processchemicalzlinesegment{B}{##3##4},
+ R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}%
+ \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalSIXFRONT[#1]%
+ {\executechemicalSIX[]%
+ %
+ \setchemicalname SIXFRONT
+ %
+ \setchemicallinesegment -R 866 500 866 100
+ \setchemicallinesegment +R 866 500 866 900
+ %
+ \setchemicaltextelement -RZ 0 -1300
+ \setchemicaltextelement +RZ 0 1300
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\def\chemicalrotation{2}%
+ \processaction
+ [##1##2##3##4]
+ [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6}
+ {,,,,,, t,t,t,t,t,t},
+ +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6}
+ {,,,,,, b,b,b,b,b,b},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4},
+ +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4},
+ BB##3##4=>\processchemicalzlinesegment{B}{##3##4},
+ R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}%
+ \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+% 1 : 0
+% 2 : -115
+% 3* : -195
+% 3 : -165
+% 4 : -245
+
+\def\executechemicalCARBON[#1]%
+ {\setchemicalname CARBON
+ %
+ \setchemicalmaximum 4
+ \setchemicaldistance 0
+ \setchemicalsubstitute 0
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423
+ \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966
+ \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966
+ \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 115 205 295 25
+ \setchemicalangle 3 165 255 345 75
+ \setchemicalangle 3* 195 285 15 105
+ \setchemicalangle 4 245 335 65 155
+ %
+ \setchemicaltranslate 1 -1500 0
+ \setchemicaltranslate 2 0 1500
+ \setchemicaltranslate 3 1500 0
+ \setchemicaltranslate 4 0 -1500
+ %
+ \setchemicallinesegment B1 500 0 1000 0
+ \setchemicallinesegment B2 300 0 1000 0
+ \setchemicallinesegment B3 500 0 1000 0
+ \setchemicallinesegment B4 300 0 1000 0
+ %
+ \setchemicaltextelement Z 1100 0
+ %
+ \setchemicalcircsegment C 0 360 500 360 0 -500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ MIR????=>\setchemicalmirror{3},
+ -MIR????=>\resetchemicalmirror{3},
+ *MIR????=>\togglechemicalmirror{3},
+ CB????=>\processlocalchemicals{B,C,Z},
+ C????=>\processchemicalcircsegment{C}{1????},
+ -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2},
+ ROT##4##5=>\processchemicalrotation{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ CB##3##4##5=>\processlocalchemicals
+ {ROT##3,C,B,Z2..4,
+ MOV##3,*MIR,-ROT##3,C,B,Z2..4},
+ B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4}
+ {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+% 1: 45 2: -90 3: -225
+% 4: -45 5: -135 6: -270
+
+\newif\ifNEWMANstagger \NEWMANstaggertrue
+
+\def\executechemicalNEWMANSTAGGER%
+ {\NEWMANstaggertrue\executechemicalNEWMAN}
+
+\def\executechemicalNEWMANECLIPSE%
+ {\NEWMANstaggerfalse\executechemicalNEWMAN}
+
+\def\executechemicalNEWMAN[#1]%
+ {\setchemicalname NEWMAN
+ %
+ \setchemicalmaximum 6
+ \setchemicaldistance 0
+ \setchemicalsubstitute 0
+ %
+ \ifNEWMANstagger
+ \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707
+ \setchemicalrotation 2 0 -1 -1 0 0 1 1 0
+ \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707
+ \else
+ \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866
+ \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259
+ \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5
+ \fi
+ \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707
+ \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707
+ \setchemicalrotation 6 0 1 1 0 0 -1 -1 0
+ %
+ \ifNEWMANstagger
+ \setchemicalangle 1 315 45 135 225
+ \setchemicalangle 2 90 180 270 0
+ \setchemicalangle 3 225 315 45 135
+ \else
+ \setchemicalangle 1 30 120 210 300
+ \setchemicalangle 2 255 345 75 165
+ \setchemicalangle 3 120 210 300 30
+ \fi
+ \setchemicalangle 4 45 135 225 315
+ \setchemicalangle 5 135 225 315 45
+ \setchemicalangle 6 270 0 90 180
+ %
+ \setchemicaltranslate 1 -1500 0
+ \setchemicaltranslate 2 0 1500
+ \setchemicaltranslate 3 1500 0
+ \setchemicaltranslate 4 0 -1500
+ %
+ \setchemicallinesegment B1 0 0 1000 0
+ \setchemicallinesegment B2 0 0 1000 0
+ \setchemicallinesegment B3 0 0 1000 0
+ \setchemicallinesegment B4 500 0 1000 0
+ \setchemicallinesegment B5 500 0 1000 0
+ \setchemicallinesegment B6 500 0 1000 0
+ %
+ \setchemicaltextelement Z 1100 0
+ %
+ \setchemicalcircsegment C 0 360 500 360 0 -500
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]},
+ ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]},
+ B????=>\processlocalchemicals{B1..6},
+ CB????=>\processlocalchemicals{B1..6,C,Z1..6},
+ C????=>\processchemicalcircsegment{C}{1????},
+ ROT##4=>\processchemicalrotation{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\ifNEWMANstagger
+ \processchemicaltextelement{Z}{##2##3##4}{#1}{6}
+ {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}%
+ \else
+ \processchemicaltextelement{Z}{##2##3##4}{#1}{6}
+ {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}%
+ \fi,
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalCHAIR[#1]% smaller
+ {\setchemicalname CHAIR
+ %
+ \setchemicalmaximum 6
+ %
+ \setchemicallinesegment B1 1600 800 2800 -800
+ \setchemicallinesegment B2 2800 -800 800 0
+ \setchemicallinesegment B3 800 0 -1600 -800
+ \setchemicallinesegment B4 -1600 -800 -2800 800
+ \setchemicallinesegment B5 -2800 800 -800 0
+ \setchemicallinesegment B6 -800 0 1600 800
+ %
+ \setchemicallinesegment +R1 1600 800 1600 1600
+ \setchemicallinesegment +R2 2800 -800 2800 -1600
+ \setchemicallinesegment +R3 800 0 800 800
+ \setchemicallinesegment +R4 -1600 -800 -1600 -1600
+ \setchemicallinesegment +R5 -2800 800 -2800 1600
+ \setchemicallinesegment +R6 -800 0 -800 -800
+ %
+ \setchemicallinesegment -R1 1600 800 2350 522 % 750 278
+ \setchemicallinesegment -R2 2800 -800 3493 -400
+ \setchemicallinesegment -R3 800 0 1329 -600 % 528 600
+ \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278
+ \setchemicallinesegment -R5 -2800 800 -3493 400
+ \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600
+ %
+ \setchemicaltextelement +RZ1 1600 1800
+ \setchemicaltextelement +RZ2 2800 -1800
+ \setchemicaltextelement +RZ3 800 1000
+ \setchemicaltextelement +RZ4 -1600 -1800
+ \setchemicaltextelement +RZ5 -2800 1800
+ \setchemicaltextelement +RZ6 -800 -1000
+ %
+ \setchemicaltextelement -RZ1 2538 453 % 200 lang
+ \setchemicaltextelement -RZ2 3666 -300
+ \setchemicaltextelement -RZ3 1460 -750
+ \setchemicaltextelement -RZ4 -2538 -453
+ \setchemicaltextelement -RZ5 -3666 300
+ \setchemicaltextelement -RZ6 -1460 750
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\def\chemicalrotation{1}%
+ \processaction
+ [##1##2##3##4##5]
+ [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6},
+ -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6},
+ +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6},
+ B##2????=>{\getchemicallinesegment[0][B##2]},
+ -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]},
+ +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]},
+ -R##3????=>{\getchemicallinesegment[0][-R##3]},
+ +R##3????=>{\getchemicallinesegment[0][+R##3]},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalarrow#1#2[#3]%
+ {\dogetcommalistelement1\from#3\to\toptext
+ \dogetcommalistelement2\from#3\to\bottext
+ \def\dochemicaltext##1%
+ {\dosetsubscripts%
+ $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$%
+ \doresetsubscripts}%
+ \doifelse\@@chemicallocation\v!intext
+ {#1{\dochemicaltext\toptext}}%
+ {\setbox\chemicalsymbols=\hbox
+ {\box\chemicalsymbols
+ \vbox{\halign{##\cr
+ \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr
+ #2%
+ \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}}
+
+\def\executechemicalGIVES
+ {\executechemicalarrow
+ {\chemicalsinglepicturearrow}% nodig
+ {\rightarrowfill\cr}}
+
+\def\executechemicalEQUILIBRIUM
+ {\executechemicalarrow
+ {\chemicaldoublepicturearrow}% nodig
+ {\rightarrowfill\cr\leftarrowfill\cr}}
+
+\def\executechemicalMESOMERIC
+ {\executechemicalarrow
+ {\chemicalsinglepicturearrow}% nodig
+ {$\leftarrow\hskip-1em$\rightarrowfill\cr}}
+
+\def\executechemicalsign#1[#2]%
+ {\doifelse\@@chemicallocation\v!intext
+ {\dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$%
+ \doresetsubscripts}
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ \dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$%
+ \doresetsubscripts}}}
+
+\def\executechemicalPLUS
+ {\executechemicalsign{+}}
+
+\def\executechemicalMINUS
+ {\executechemicalsign{-}}
+
+\def\executechemicalEQUAL
+ {\executechemicalsign{=}}
+
+\def\executechemicalSPACE[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ \quad}}}
+
+\def\executechemicalCHEM[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$}}}
+
+\def\executechemicalTEXT[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols#1}}}
+
+%\def\executechemicalLOW[#1]%
+% {\setlowsubscripts}
+%
+%\def\executechemicalHIGH[#1]%
+% {\sethighsubscripts}
+
+\def\putchemicalrule#1#2#3#4%
+ {\ifcase\chemicaldrawingmode
+ \putrule from {#1} {#2} to {#3} {#4}
+ \or
+ \psline(#1,#2)(#3,#4)%
+ \or
+ \bgroup
+ \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ draw z1--z2 ;
+ \stopMPdrawing
+ \egroup
+ \fi}
+
+\def\executechemicalcomplex#1%
+ {\bgroup
+ \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}%
+ \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}%
+ \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}%
+ \egroup}
+
+\def\executechemicalOPENCOMPLEX[#1]%
+ {\executechemicalcomplex+\ignorespaces
+ \executechemicalSPACE[]}
+
+\def\executechemicalCLOSECOMPLEX[#1]%
+ {\executechemicalSPACE[]%
+ \executechemicalcomplex-\ignorespaces}
+
+% nog niet door midden as!
+
+\def\executechemicalverticalsymbol#1#2%
+ {\executechemicalTEXT
+ [$\left#1\relax
+ \dimen0=\@@chemicalunit
+ \scratchcounter=\@@chemicaltop
+ \advance\scratchcounter by \@@chemicalbottom
+ \dimen0=\scratchcounter\dimen0
+ \vcenter to \dimen0{}
+ \dimen2=\@@chemicalunit
+ \dimen2=\@@chemicalright\dimen0
+ \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}%
+ \right.$]}%
+
+\def\executechemicalUPARROW[#1]%
+ {\executechemicalverticalsymbol\uparrow{#1}}
+
+\def\executechemicalDOWNARROW[#1]%
+ {\executechemicalverticalsymbol\downarrow{#1}}
+
+\def\executechemicalUPDOWNARROW[#1]%
+ {\executechemicalverticalsymbol\updownarrow{#1}}
+
+\let\setchemicalattributes\relax
+
+\setupchemical
+ [\c!width=0,
+ \c!height=0,
+ \c!left=0,
+ \c!right=0,
+ \c!top=0,
+ \c!bottom=0,
+ \c!bodyfont=\the\bodyfontsize,
+ \c!resolution=\outputresolution,
+ \c!scale=\v!medium,
+ \c!size=\v!medium,
+ \c!textsize=\v!big,
+ \c!frame=\v!off,
+ \c!axis=\v!off,
+ \c!state=\v!start,
+ \c!style=\rm,
+ \c!location=,
+ \c!option=,
+ \c!offset=LOW,
+ \c!alternative=1,
+ \c!color=,
+ \c!rulethickness=,
+ \c!rulecolor=,
+ \c!factor=1]
+
+% Tijdelijk plaatsen we deze extra macro's hier.
+%
+% mathontop: \mtop {} {}
+% textontop: \ttop {} {}
+
+\def\putontop#1#2%
+ {\vbox
+ {\halign
+ {\strut\hss##\hss\cr
+ #1\cr
+ #2\cr}}}
+
+\def\ttop#1#2%
+ {\putontop{\tx#1}{#2}}
+
+\def\mtop#1#2%
+ {\vbox
+ {\offinterlineskip
+ \halign
+ {\hss##\hss\cr
+ $\scriptscriptstyle#1$\cr
+ \noalign{\vskip.5ex}%
+ $#2$\cr}}}
+
+\def\ctop#1#2%
+ {\vbox
+ {\offinterlineskip
+ \halign
+ {\hss##\hss\cr
+ $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr
+ \noalign{\vskip.5ex}%
+ $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}}
+
+%D Here are a couple of \CONTEXT\ goodies:
+%D
+%D \startitemize
+%D \item styles hooked into \CONTEXT\ style mechanism
+%D \item support for color and rulethickness (mp mode only)
+%D \item position tracking
+%D \stopitemize
+
+\ifCONTEXT \else \protect \endinput \fi
+
+\let\@@chemicalrulecolor\empty
+\let\@@chemicalcolor \empty
+
+% \def\setchemicalattributes
+% {\scratchdimen\@@chemicalchemicalrulethickness
+% \def\chemicalattributes
+% {withpen pencircle scaled \the\scratchdimen\space
+% withcolor }%
+% \doifelsenothing\@@chemicalchemicalrulecolor
+% {\edef\chemicalattributes{\chemicalattributes black}}
+% {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalchemicalrulecolor}}}%
+% \startMPdrawing
+% drawoptions (\chemicalattributes) ;
+% \stopMPdrawing}
+
+\def\setchemicalattributes
+ {\scratchdimen\@@chemicalrulethickness
+ \def\chemicalattributes
+ {withpen pencircle scaled \the\scratchdimen\space
+ withcolor }%
+ \doifelsenothing\@@chemicalrulecolor
+ {\edef\chemicalattributes{\chemicalattributes black}}
+ {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}%
+ \startMPdrawing
+ drawoptions (\chemicalattributes) ;
+ \stopMPdrawing}
+
+\def\@@dochemicalcolor
+ {\doifsomething\@@chemicalcolor{\color[\@@chemicalcolor]}}
+
+\def\@@dochemicalstyle
+ {\doconvertfont\@@chemicalstyle}
+
+\setupchemical
+ [\c!rulethickness=\linewidth,
+ \c!rulecolor=,
+ \c!color=]
+
+\def\cpos#1#2%
+ {\iftrialtypesetting
+ #2%
+ \else
+ \bgroup
+ \globalpushmacro\dowithchemical
+ \gdef\dowithchemical##1{\hpos{#1}{##1}\globalpopmacro\dowithchemical}%
+ #2%
+ \egroup
+ \fi}
+
+\protect \endinput
+
+% \startchemical[axis=on,frame=yes]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=small,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=medium,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=big,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
diff --git a/tex/context/modules/mkii/rlxcache.rlx b/tex/context/modules/mkii/rlxcache.rlx
new file mode 100644
index 000000000..006e5feac
--- /dev/null
+++ b/tex/context/modules/mkii/rlxcache.rlx
@@ -0,0 +1,71 @@
+<?xml version='1.0 standalone='yes'?>
+
+<rl:manipulators>
+
+ <rl:manipulator name='pdf' suffix='eps'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.eps</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.eps"
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='svg'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svg</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.svg"
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='svgz'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svgz</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.svgz"
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='gif'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.gif</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.gif"
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='tif'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.tif</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.tif"
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='tiff'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.tiff</rl:old>
+ <rl:new><rl:value name='cache' default='rlxcache'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath="<rl:value name='path'/>"
+ --outputpath="<rl:value name='cache' default='.'/>"
+ "<rl:value name='file' method='nosuffix'/>.tiff"
+ </rl:step>
+ </rl:manipulator>
+
+</rl:manipulators>
diff --git a/tex/context/modules/mkii/rlxtools.rlx b/tex/context/modules/mkii/rlxtools.rlx
new file mode 100644
index 000000000..b230c6d5b
--- /dev/null
+++ b/tex/context/modules/mkii/rlxtools.rlx
@@ -0,0 +1,136 @@
+<?xml version='1.0 standalone='yes'?>
+
+<rl:manipulators>
+
+ <!-- normally the file tag will also have a suffix! -->
+
+ <!-- pstopdf will be made independent of the example framework -->
+
+ <!-- rl:manipulator name='pdf' suffix='svg'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file'/></rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ inkscape
+ --without-gui
+ --print="&gt;<rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.ps"
+ <rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svg
+ </rl:step>
+ <rl:step>
+ texmfstart pstopdf
+ <rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.ps
+ <rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf
+ </rl:step>
+ </rl:manipulator -->
+
+ <!-- rl:manipulator name='pdf' suffix='svgz'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file'/></rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ inkscape
+ --without-gui
+ --print="&gt;<rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.ps"
+ <rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svgz
+ </rl:step>
+ <rl:step>
+ texmfstart pstopdf
+ <rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.ps
+ <rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf
+ </rl:step>
+ </rl:manipulator -->
+
+ <rl:manipulator name='pdf' suffix='eps'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.eps</rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ <rl:value name='old'/>
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='svg'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svg</rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ <rl:value name='old'/>
+ <rl:value name='new'/>
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='svgz'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.svgz</rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ <rl:value name='old'/>
+ <rl:value name='new'/>
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='lowres' suffix='pdf'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file'/></rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file'/></rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert --method=4
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='path'/>/<rl:value name='prefix'/>
+ <rl:value name='file'/>
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='medres' suffix='pdf'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file'/></rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file'/></rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert --method=4
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='path'/>/<rl:value name='prefix'/>
+ <rl:value name='file'/>
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='gif'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.gif</rl:old>
+ <rl:new><rl:value name='cache' default='.'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='cache' default='.'/>
+ <rl:value name='file' method='nosuffix'/>.gif
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='tif'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.tif</rl:old>
+ <rl:new><rl:value name='cache' default='.'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='cache' default='.'/>
+ <rl:value name='file' method='nosuffix'/>.tif
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='pdf' suffix='tiff'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file' method='nosuffix'/>.tiff</rl:old>
+ <rl:new><rl:value name='cache' default='.'/>/<rl:value name='file' method='nosuffix'/>.pdf</rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='cache' default='.'/>
+ <rl:value name='file' method='nosuffix'/>.tiff
+ </rl:step>
+ </rl:manipulator>
+
+ <rl:manipulator name='cropped' suffix='pdf'>
+ <rl:old><rl:value name='path'/>/<rl:value name='file'/></rl:old>
+ <rl:new><rl:value name='path'/>/<rl:value name='prefix'/><rl:value name='file'/></rl:new>
+ <rl:step>
+ texmfstart pstopdf --convert --method=3
+ --inputpath=<rl:value name='path'/>
+ --outputpath=<rl:value name='path'/>/<rl:value name='prefix'/>
+ <rl:value name='file'/>
+ </rl:step>
+ </rl:manipulator>
+
+</rl:manipulators>
diff --git a/tex/context/modules/mkii/s-chi-00.mkii b/tex/context/modules/mkii/s-chi-00.mkii
new file mode 100644
index 000000000..fb8d47603
--- /dev/null
+++ b/tex/context/modules/mkii/s-chi-00.mkii
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=s-chi-00,
+%D version=1999.12.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Basic Chinese Style,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions=Wang Lei,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\input font-chi.mkii % faster than \setupbodyfont[chi]
+
+\mainlanguage [cn]
+
+\unprotect
+
+\setupsection [\s!section-1] [\c!headconversion=\s!chinese]
+\setupsection [\s!section-2] [\c!headconversion=\s!chinese]
+\setupsection [\s!section-3] [\c!headconversion=\s!chinese]
+
+\setupsection [\s!section-2] [\v!appendix\c!conversion=]
+
+\setuphead [\v!chapter] [\c!distance=1.25em]
+\setuphead [\v!section] [\c!distance=1.25em]
+\setuphead [\v!subsection] [\c!distance=1.00em]
+
+\setuplist [\v!chapter] [\c!headlabel=\v!yes,\c!headconversion=\v!yes,\c!width=5em]
+\setuplist [\v!section] [\c!headlabel=\v!yes,\c!headconversion=\v!yes,\c!width=5em]
+
+\setupmarking [\v!chapter\v!number] [\c!headlabel=\v!yes,\c!headconversion=\v!yes]
+\setupmarking [\v!section\v!number] [\c!headlabel=\v!yes,\c!headconversion=\v!yes]
+
+\setuplabeltext [cn] [\v!subsection={\symbol[S]\kern.25em}]
+\setuplabeltext [cn] [\v!subsubsection={\symbol[S]\kern.25em}]
+\setuplabeltext [cn] [\v!subsubsubsection={\symbol[S]\kern.25em}]
+\setuplabeltext [cn] [\v!subsubsubsubsection={\symbol[S]\kern.25em}]
+
+% nog taalonafhankelijk maken -> \e!tabel enz
+
+\definereferenceformat [intable] [\c!label=\v!table]
+\definereferenceformat [infigure] [\c!label=\v!figure]
+\definereferenceformat [inchapter] [\c!label=\v!chapter]
+\definereferenceformat [insection] [\c!label=\v!section]
+
+% important
+
+\setuptyping[\c!tab=\v!no]
+
+%D This module (and font support) adapts to the \UTF\ regime, but you
+%D need to enable \UTF\ first!
+%D
+%D \starttyping
+%D \enableregime[utf] \usemodule[chi-00]
+%D
+%D \starttext
+%D
+%D 兡也包因沘氓侷柵苗孫孫財
+%D 崧淫設弼琶跑愍窟榜蒸奭稽
+%D 霄瓢館縲擻鼕孃魔釁佉沎岠
+%D 狋垚柛胅娭涘罞偟惈牻荺傒
+%D 焱菏酡廅滘絺赩塴榗箂踃嬁
+%D 澕蓴醊獧螗餟燱螬駸礑鎞瀧
+%D 鄿瀯騬醹躕鱕
+%D
+%D \blank
+%D
+%D Wang Lei is written as: 王磊
+%D
+%D \stoptext
+%D \stoptyping
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/s-fnt-01.mkii b/tex/context/modules/mkii/s-fnt-01.mkii
new file mode 100644
index 000000000..aedcf913d
--- /dev/null
+++ b/tex/context/modules/mkii/s-fnt-01.mkii
@@ -0,0 +1,61 @@
+%D \module
+%D [ file=s-fnt-01,
+%D version=2001.08.22,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Font Environment 1,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This file is used by the \type {texfont.pl} installation
+%D script. It is of no use for \MKIV.
+
+%D Modes: compact
+
+\dontcomplain
+
+\setupbodyfont
+ [10pt]
+
+\setuplayout
+ [backspace=30pt,
+ topspace=30pt,
+ footer=0pt,
+ header=36pt,
+ width=middle,
+ height=middle]
+
+\setupcolors
+ [state=start]
+
+\def\ShowFont
+ {\dotripleempty\doShowFont}
+
+\def\doShowFont[#1][#2][#3]%
+ {\doifsomething{#1}
+ {\bgroup
+ \ifthirdargument
+ \definefontsynonym[WhateverName][#2][encoding=#3]
+ \definefont[WhateverFont][WhateverName]
+ \setupheadertexts[\tttf#2\quad#1\quad#3]
+ \WhateverFont
+ \setupinterlinespace
+ \showfont[WhateverName]
+ \showligatures[WhateverName]
+ \doifnotmode{compact}{\showaccents\showcharacters}
+ \else
+ \definefontsynonym[WhateverName][#2]
+ \definefont[WhateverFont][WhateverName]
+ \setupheadertexts[\tttf#2\quad#1\quad(special font)]
+ \WhateverFont
+ \setupinterlinespace
+ \showfont[WhateverName]
+ \fi
+ \page
+ \egroup}}
+
+\endinput
diff --git a/tex/context/modules/mkii/s-fnt-02.mkii b/tex/context/modules/mkii/s-fnt-02.mkii
new file mode 100644
index 000000000..69f976102
--- /dev/null
+++ b/tex/context/modules/mkii/s-fnt-02.mkii
@@ -0,0 +1,133 @@
+% output=pdftex modes=demo
+
+% nice example:
+%
+% \usemodule[s-fnt-02]
+%
+% \usetypescriptfile[type-ghz.tex]
+%
+% \usetypescript [sans] [optima,optima-nova] [texnansi]
+%
+% \setvariables
+% [glyphs]
+% [name-1=OptimaLT,
+% name-2=OptimaNovaLT-Regular]
+%
+% \starttext
+%
+% \setups[show-glyphs]
+%
+% \stoptext
+%
+% see end, for other example (or run texexec s-fnt-02 --mode=demo)
+
+\setvariables
+ [glyphs]
+ [frame=on,
+ name-1=cmr10,
+ name-2=cmtt10,
+ map-1=,
+ map-2=]
+
+\setuppapersize[S4][S4]
+
+\setupcolors[state=start]
+
+\setuplayout[page]
+
+\definecolor[Gray] [s=.2]
+\definecolor[ColorNone][s=1,t=.5,a=1]
+\definecolor[ColorOne] [r=1,t=.5,a=1]
+\definecolor[ColorTwo] [g=1,t=.5,a=1]
+\definecolor[BackOne] [b=1,t=.5,a=1]
+\definecolor[BackTwo] [r=1,g=1,t=.5,a=1]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=Gray]
+
+\startsetups[show-glyphs]
+
+ \doifnothing{\getvariable{glyphs}{name-1}}{\endinput}
+ \doifnothing{\getvariable{glyphs}{name-2}}{\endinput}
+
+ \doifsomething{\getvariable{glyphs}{map-1}}{\loadmapfile[\getvariable{glyphs}{map-1}]}
+ \doifsomething{\getvariable{glyphs}{map-2}}{\loadmapfile[\getvariable{glyphs}{map-2}]}
+
+ \definefont[FontOne][\getvariable{glyphs}{name-1} at 280pt]
+ \definefont[FontTwo][\getvariable{glyphs}{name-2} at 280pt]
+
+% \dostepwiserecurse{0}{255}{1}
+% {\doiffontcharelse{\getvariable{glyphs}{name-1}}{\recurselevel}
+% {\doiffontcharelse{\getvariable{glyphs}{name-2}}{\recurselevel}
+% {\startstandardmakeup
+% \doifelse{\getvariable{glyphs}{frame}}{on} % too many box calculations when off, but who cares
+% {\boxrulewidth=2pt}
+% {\boxrulewidth=0pt}
+% \setbox 0=\hbox{\white\ruledhbox{\FontOne \char\recurselevel}}
+% \setbox 2=\hbox{\white\ruledhbox{\FontTwo \char\recurselevel}}
+% \setbox 4=\hbox{\FontOne \ColorOne \char\recurselevel}
+% \setbox 6=\hbox{\FontTwo \ColorTwo \char\recurselevel}
+% \setbox 8=\hbox{\BackOne \ruledhbox{\FontOne \phantom{\char\recurselevel}}}
+% \setbox10=\hbox{\BackTwo \ruledhbox{\FontTwo \phantom{\char\recurselevel}}}
+% \vfill
+% \hbox{\dostepwiserecurse{0}{10}{2}{\hbox to \hsize{\hss\box\recurselevel\hss}\hskip-\hsize}}
+% \vfill
+% \tttf
+% \setstrut
+% \hbox to \hsize{\strut\hss
+% {\ColorOne \getvariable{glyphs}{name-1}}\quad
+% {\ColorTwo \getvariable{glyphs}{name-2}}\quad
+% {\ColorNone char \recurselevel }\hss}
+% \stopstandardmakeup}
+% {}}
+% {}}
+
+ \dostepwiserecurse{0}{255}{1}
+ {\donefalse
+ \doiffontcharelse{\getvariable{glyphs}{name-1}}{\recurselevel}{\donetrue}{}%
+ \doiffontcharelse{\getvariable{glyphs}{name-2}}{\recurselevel}{\donetrue}{}%
+ \ifdone
+ \startstandardmakeup
+ \doifelse{\getvariable{glyphs}{frame}}{on} % too many box calculations when off, but who cares
+ {\boxrulewidth=2pt}
+ {\boxrulewidth=0pt}
+ \setbox 0=\hbox{\white\ruledhbox{\FontOne \char\recurselevel}}
+ \setbox 2=\hbox{\white\ruledhbox{\FontTwo \char\recurselevel}}
+ \setbox 4=\hbox{\FontOne \ColorOne \char\recurselevel}
+ \setbox 6=\hbox{\FontTwo \ColorTwo \char\recurselevel}
+ \setbox 8=\hbox{\BackOne \ruledhbox{\FontOne \phantom{\char\recurselevel}}}
+ \setbox10=\hbox{\BackTwo \ruledhbox{\FontTwo \phantom{\char\recurselevel}}}
+ \vfill
+ \hbox{\dostepwiserecurse{0}{10}{2}{\hbox to \hsize{\hss\box\recurselevel\hss}\hskip-\hsize}}
+ \vfill
+ \tttf
+ \setstrut
+ \hbox to \hsize{\strut\hss
+ {\ColorOne \getvariable{glyphs}{name-1}}\quad
+ {\ColorTwo \getvariable{glyphs}{name-2}}\quad
+ {\ColorNone char \recurselevel }\hss}
+ \stopstandardmakeup
+ \fi}
+
+\stopsetups
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+ \setupencoding[default=ec]
+
+ \loadmapline [=][aer10 <cmr10.pfb]
+ \loadmapline [=][\defaultencoding-lmr10 <\defaultencoding.enc <lmr10.pfb]
+
+ \setvariables
+ [glyphs]
+ [frame=on,
+ name-1=aer10,
+ name-2=\defaultencoding-lmr10]
+
+ \setups[show-glyphs]
+
+\stoptext
diff --git a/tex/context/modules/mkii/s-grk-00.mkii b/tex/context/modules/mkii/s-grk-00.mkii
new file mode 100644
index 000000000..f76d0c220
--- /dev/null
+++ b/tex/context/modules/mkii/s-grk-00.mkii
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=s-grk-00,
+%D version=2004.08.23,
+%D title=\CONTEXT\ Style File,
+%D subtitle=CB Greek Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions=Giuseppe Bilotta,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usetypescriptfile[type-cbg]
+
+\usetypescript [all] [cbgreek-medium]
+
+\startsetups [cbgreek]
+
+ \catcode`~=\other
+ \catcode`|=\other
+
+ \language[greek]
+ \switchtobodyfont[cbgreek]
+
+\stopsetups
+
+\definestartstop
+ [greek]
+ [commands=\directsetup{cbgreek}]
+
+\doifnotmode{demo}{\endinput}
+
+% The following sample file was submitted to the \CONTEXT\
+% mailing list by Giuseppe Bilotta, along with the right
+% typescripts.
+
+% already loaded: \usemodule[greek]
+
+\mainlanguage[english]
+
+\starttext
+
+We can easily use plain English for normal text, and then switch
+to greek when we want; as a first try we type the lower and
+upper case 26 letters of the latin alphabet and see how they come
+out in greek:
+
+\startgreek
+a b c d e f g h i j k l m n o p q r s t u v w x y z \par
+A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+\stopgreek
+
+As it can be observed, some uppercase letters have strange
+outcomes; also, j gives \greek{j} and c gives the
+end-of-word sigma \greek{c}; interestingly, s gives either the
+normal sigma or the end-of-word one, depending on whether it's at
+the end of the word or not: \greek{satrapws}.
+
+Of course we can use the various diacritical signs: accents
+(\greek{`a, 'a, ~a}), breathings (\greek{<r, >w, a"}) and
+subscribed iotas (\greek{a|, h|, w|}) (these last are pretty ugly in my
+opinion); observe how they automatically get the correct position
+with uppercase letters: (\greek{`A, 'A, ~A, <A, >A, A|}).
+
+Can the thing be used for serious work?
+
+\startgreek
+>>'Andra moi >'ennepe, Mo~usa, pol'utropon, >'os m'ala poll`a\hfill\break
+pl'agqjh, >epe`i Tro'ihs <er`on ptol'iejron >'eperse;\hfill\break
+poll~wn d" >anjr'wpwn >'iden >'astea ka`i n'oon >'egnw,\hfill\break
+poll`a d" <'o g" >en p'ontw| p'ajen >'algea <`on kat`a jum'on,\hfill\break
+>>arn'umenos <'hn te yuq`hn ka`i n'oston <eta'irwn.
+\stopgreek
+
+\stoptext
diff --git a/tex/context/modules/mkii/s-jap-00.mkii b/tex/context/modules/mkii/s-jap-00.mkii
new file mode 100644
index 000000000..5eec2f725
--- /dev/null
+++ b/tex/context/modules/mkii/s-jap-00.mkii
@@ -0,0 +1,23 @@
+%D \module
+%D [ file=s-jap-00,
+%D version=2006.01.19,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Basic Japanese Style,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions=Richard Gabriel,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\input font-jap.tex % faster than \setupbodyfont[jap]
+
+\mainlanguage [ja]
+
+\unprotect
+
+\setuptyping[\c!tab=\v!no]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/s-map-10.mkii b/tex/context/modules/mkii/s-map-10.mkii
new file mode 100644
index 000000000..3446a214c
--- /dev/null
+++ b/tex/context/modules/mkii/s-map-10.mkii
@@ -0,0 +1,491 @@
+%\module [
+% file=s-map-10.mkii,
+% version=2012.06.06,
+% title=\CONTEXT\ Style File,
+% subtitle=\MAPS\ journal style,
+% author={Hans Hagen, Taco Hoekwater and Siep Kroonenberg},
+% date=\currentdate,
+% copyright={NTG / MAPS}%
+%]
+
+% NOTE: this (MkII) version is not guaranteed to give exactly the
+% same output as the MkIV one, and exists mostly for compatibility
+% with old-fashioned authors. All final typesetting for the MAPS
+% is done with MkIV. If you are reading this: please consider
+% switching!
+
+% This module implements the MAPS style for use with the Context
+% macro package. The original MAPS layout was designed and
+% implemented in LaTeX by Taco Hoekwater and Siep Kroonenberg.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newif\ifMapsInColumns
+\doifmode{asym}{\enablemode[onecolumn]} % implies onecolumn
+\doifnotmode{onecolumn}{\MapsInColumnstrue}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% fonts
+
+%%%%%%%%% first, font sizes
+\definebodyfontenvironment [7pt][% LaTeX: scriptsize
+ interlinespace=8pt,
+ big=8pt,
+ small=6pt%
+]
+
+\definebodyfontenvironment [8pt][% LaTeX: footnotesize
+ interlinespace=9pt,
+ big=9pt,
+ small=7pt,
+ x=6pt%
+]
+
+\definebodyfontenvironment [9pt][% LaTeX: small
+ interlinespace=10pt,
+ big=10pt,
+ small=8pt,%
+ x=7pt,%
+ script=6pt%
+]
+
+\definebodyfontenvironment [10pt][% LaTeX: normalsize
+ interlinespace=11pt,
+ big=11pt,
+ a=11pt,
+ small=9pt,%
+ x=8pt,%
+ script=7pt%
+]
+
+\definebodyfontenvironment [11pt][% LaTeX: large
+ interlinespace=11pt,
+ big=11pt,
+ small=10pt,%
+ x=9pt,%
+ script=8pt%
+]
+
+\definebodyfontenvironment [14pt][%
+ interlinespace=14pt,
+ big=18pt,
+ small=11pt,
+ x=10pt%
+]
+
+\definebodyfontenvironment [18pt][%
+ interlinespace=18pt,
+ big=24pt,
+ small=14pt,
+ x=10pt%
+]
+
+\definebodyfontenvironment [24pt][%
+ interlinespace=24pt,
+ big=24pt,
+ small=18pt,
+ x=11pt%
+]
+
+%%% font families (no realfonts, no protruding)
+
+\starttypescript [maps][ec]
+\definetypeface [maps] [rm] [serif] [modern] [default] [encoding=ec,rscale=0.95]
+\definetypeface [maps] [mm] [math] [modern] [computer-modern]
+\definetypeface [maps] [tt] [mono] [modern] [default] [encoding=ec,rscale=0.90]
+\definetypeface [maps] [ss] [sans] [modern] [default] [encoding=ec,rscale=0.95]
+\stoptypescript
+
+\writestatus{maps\space warning}{This, the MkII style, is OUTDATED and UNSUPPORTED!}
+\writestatus{maps\space warning}{Please consider using ConTeXt MkIV instead.}
+
+\startmode[realfonts]
+\writestatus{maps\space error}{The MkII version of the module does not support 'realfonts'!}
+\wait
+\stopmode
+
+\setupbodyfont[maps,10pt,rm]
+
+\setupinterlinespace[line=11pt]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% additional general typographic details
+
+\setupindenting [yes,next,11pt] % indenting after enumerations etc.
+
+\definepapersize
+ [maps]
+ [width=21cm,height=26.5cm]
+
+\setuppapersize [maps][maps]
+
+% parameters:
+% margin -> latex marginparwith
+
+\setuplayout[%
+ topspace=40pt,
+ height=688pt,
+ header=33pt,
+ margin=106pt,
+ leftmargindistance=11pt,
+ rightmargindistance=11pt%
+]
+
+
+\setupblank[5.5pt]
+
+\setuppagenumbering [location=]
+
+\definetyping [widetyping]
+
+\setupheader [style=\ss]
+\setupfooter [style=\ss]
+
+\def\AuHead{%
+ %\ifnum\pageno=\MapsPage \hbox{}\else
+ \MapsRunningAuthor%\fi
+}
+\def\TiHead{%
+ \ifnum\pageno=\MapsPage \relax \MapsRunningAuthor %\hbox{}
+ \else \MapsRunningTitle\fi}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% sectioning
+
+\setupheads[sectionnumber=no, align=right]
+
+\def\hfonti{\ssbfa}
+\def\hfontii{\ssbf}
+\def\hfontiii{\rm\it}
+\def\runin#1#2{#2.}
+
+\doifmodeelse{nosubsub}{%
+\setuphead [section][%
+ style=\hfontii,
+ before={\blank[line]},
+ after={}%
+]
+\setuphead [subsection][%
+ style=\hfontiii,
+ command=\runin,
+ alternative=text,
+ distance=6pt,
+ before={\blank[halfline]}%
+]}{%
+\setuphead [section][%
+ style=\hfonti,
+ before={\blank[line]},
+ after={\blank[halfline]}%
+]
+\setuphead [subsection][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubsection][%
+ style=\hfontiii,
+ command=\runin,
+ distance=6pt,
+ alternative=text,
+ before={\blank[halfline]}%
+]}
+
+\doifmodeelse{nosubsub}{%
+\setuphead [subject][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubject][%
+ style=\hfontiii,
+ command=\runin,
+ alternative=text,
+ before={\blank[halfline]}%
+]}{%
+\setuphead [subject][%
+ style=\hfonti,
+ before={\blank},
+ after={\blank[halfline]}%
+]
+\setuphead [subsubject][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubsubject][%
+ style=\hfontiii,
+ command=\runin,
+ alternative=text,
+ before={\blank[halfline]}%
+]}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% floats
+
+\setupfloats [location=center, before={\ss}]
+\setupcaptions [headstyle={\ssbf},style={\ssx},
+ suffix=,distance=6pt,
+ inbetween={\blank[halfline]}]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% various document elements
+
+\def\ChkBox{%
+ \hbox {\boxrulewidth=.4pt \raise.2ex\ruledvbox
+ {\phantom{\vrule width .85ex height .85ex%
+}}}}
+\definesymbol [1][\ChkBox]
+
+\setupitemize[1][packed]
+
+\setupitemize [each][%
+ indentnext=no,
+ align=right,
+ width=1em,
+ distance=0pt%
+]
+
+% an outer form of itemize that does not indent
+% the paragraph.
+
+\definecomplexorsimpleempty\startouteritemize
+\def\complexstartouteritemize[#1]{\begingroup
+ \startitemize[width=1sp,#1]
+ \let\doitem\item
+ \def\item{\doitem[]\hbox{}\kern12pt\rightskip=0pt}%
+}
+
+\def\stopouteritemize{\stopitemize\endgroup}
+
+
+\setupenumerations [indentnext=no]
+
+\setupdescriptions [indentnext=no]
+
+\unexpanded\def\smalltyping{%
+ \switchtobodyfont[tt]%
+ \parindent=0pt
+}
+
+% typing:
+% - prettyverbatim is NOT the default
+% - smaller size
+
+\unexpanded\def
+ \XeTeX{X\lower.5ex\hbox{\kern-.1em\mirror{E}}\kern-.1667em\TeX}
+
+\setuptyping [%
+ style={\smalltyping},
+ option=none,
+ indentnext=no%
+]
+
+\def\footnum#1{#1.}
+
+\setupfootnotes
+ [location=none,
+ width=\textwidth,
+ before={\blank},
+ numbercommand=,
+ command=\footnum]
+
+\setupfootnotedefinition
+ [location=serried,
+ before=,
+ after=,
+ distance=0.5em]
+
+\setuptabulate
+ [before=\blank,
+ inner=\ss,
+ after=\blank]
+
+\def\startIntroEntry#1%
+ {\startlinecorrection
+ \bgroup
+ \setupalign[right]
+ \setuptolerance[verytolerant]
+ \setupindenting[no]
+ \noindent
+ \switchtobodyfont[9pt]%
+ \setuplocalinterlinespace[line=10pt]%
+ %\hyphenpenalty10000
+ \parfillskip 0pt plus 1fill
+ \rightskip6pt plus 1fill
+ \ss
+ \bgroup\bf #1\par\egroup
+ \ignorespaces }
+
+\def\stopIntroEntry
+ {\par\egroup \stoplinecorrection
+ \blank[line] }
+
+\def\defineIntroEntry[#1][#2][#3]%
+ {\setvalue{start#1}{\startIntroEntry{#2}}%
+ \setvalue {stop#1}{\stopIntroEntry#3}}
+
+\defineIntroEntry[Keywords][Keywords][]
+\defineIntroEntry[Abstract][Abstract][]
+
+% article parameters (other fields and defaults)
+\def\MapsBibData[#1]%
+ {\getparameters [Maps]
+ [SubTitle=,
+ RunningAuthor=,
+ RunningTitle=,
+ Email=,
+ Address=,
+ Page=1,
+ Title=,
+ Author=,
+ Period=,
+ Number=,
+ Year=,
+ #1]%
+ \doifnothing{\MapsPeriod}{%
+ \ifnum \normalmonth<6 \gdef\MapsPeriod{VOORJAAR}\else \gdef\MapsPeriod{NAJAAR}\fi}
+ \doifinstringelse{oorjaar}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}%
+ \doifinstringelse{pring}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}%
+ \doifinstringelse{ajaar}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}%
+ \doifinstringelse{utumn}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}%
+ \doifnothing{\MapsYear}{\gdef\MapsYear{\the\year}}%
+ \doifnothing{\MapsNumber}{%
+ \ifnum \normalmonth<6
+ \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2\relax}%
+ \else
+ \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2+1\relax}%
+ \fi }%
+ \doifnothing\MapsRunningAuthor
+ {\global\let\MapsRunningAuthor\MapsAuthor}%
+ \doifnothing\MapsRunningTitle
+ {\global\let\MapsRunningTitle\MapsTitle}}%
+
+\def\dostartArticle[#1]{%
+ \MapsBibData[#1]
+ \pageno=\MapsPage
+ \setuppagenumber[start=\MapsPage]
+ \startbaselinecorrection
+ \bgroup
+ \hsize = 457pt
+ \let\\\crlf
+ \blank[35pt,force]
+ \switchtobodyfont[24pt]
+ \setupalign[right]
+ {\noindent\bf\MapsTitle\par}
+ \ifx\MapsSubTitle\empty
+ \blank[30pt]
+ \else
+ \bgroup
+ \blank[12pt]
+ \switchtobodyfont[18pt]\noindent \it
+ \advance \rightskip 0pt plus 2em
+ \MapsSubTitle\par
+ \egroup
+ \blank[30pt]
+ \fi
+ \egroup
+ \setupalign[width]
+ \switchtobodyfont[rm,10pt]
+ \stopbaselinecorrection
+ \ifMapsInColumns
+ \startcolumns\hyphenpenalty1000
+ \else
+ \clubpenalty10000
+ \widowpenalty10000
+ \fi
+}
+
+\def\startArticle{\dosingleempty\dostartArticle}
+
+\def\signArticle{%
+ \blank\let\\\crlf
+ \noindent\switchtobodyfont[ss,9pt]%
+ \MapsAuthor
+ \doifsomething{\MapsAddress}{\\\MapsAddress}%
+ \doifsomething{\MapsEmail}{\\\MapsEmail}%
+ \switchtobodyfont[10pt]%
+ \def\signArticle{}%
+}
+
+\def\stopArticle{%
+ \par\signArticle
+ \ifMapsInColumns \stopcolumns \fi
+ \page
+}
+
+\installpagebreakhandler{last}{}
+
+%%% `logos' %%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\unexpanded\def\LaTeX % requested by erik frambach
+ {{\setbox\scratchbox\hbox{L}%
+ \scratchdimen\ht\scratchbox
+ \setbox\scratchbox\hbox{\switchtobodyfont[script]A}%
+ L\kern-.55\wd\scratchbox
+ \raise\scratchdimen\hbox{\lower\ht\scratchbox\copy\scratchbox}%
+ \kern-.2\wd\scratchbox\TeX}}
+
+
+\def\CONTEXT{Con{\TeX}t}
+\def\ConTeXt{Con{\TeX}t}
+\def\METAFONT{Metafont}
+\def\METAPOST{MetaPost}
+\def\POSTSCRIPT{PostScript}
+
+\def\acro#1{{\switchtobodyfont[9pt]#1}}
+
+
+%%%%%%%%%%%
+
+\doifmodeelse{onecolumn}{%
+ \setuplayout[width=340pt]
+ \doifmodeelse{asym}{% one col, asymmetric
+ \setuplayout[backspace=187.3pt]%
+ \setuptyping [widetyping][oddmargin=-117pt]
+ \setuppagenumbering [alternative={singlesided,doublesided}]
+ \setupheadertexts
+ [{\hbox{}\hskip-117pt\TiHead}]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}]
+ [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+ }{% one col, symmetric
+ \setuplayout[backspace=70.3pt]
+ \setuppagenumbering [alternative=doublesided]
+ \setuptyping[blank=halfline]
+ \setupheadertexts
+ [\TiHead]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-147pt\hbox{}}]
+ [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+}}{% two col
+ \setuplayout[width=457pt]
+ \setupcolumns[n=2,tolerance=verytolerant,distance=11pt]
+ \setuplayout[backspace=70.3pt,grid=yes]
+ \setuppagenumbering [alternative=doublesided]
+ \setuptyping[blank=halfline]
+ \setupheadertexts
+ [\TiHead]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}]
+ [{\hbox{}\hskip-30pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+}
+
+\def\fulltextwidth{457pt}
+
+\def\startdescription
+ {\blank
+ \bgroup
+ \def\sym##1{\par\noindent\hbox{\bf\kern -16pt ##1}\hskip 12pt}
+ \startnarrower[left]
+ }
+\def\stopdescription
+ {\par \stopnarrower \egroup \blank \noindentation }
+
+\frenchspacing
+\setuptolerance[tolerant]
+
+\endinput
diff --git a/tex/context/modules/mkii/s-mod-00.mkii b/tex/context/modules/mkii/s-mod-00.mkii
new file mode 100644
index 000000000..a81406a73
--- /dev/null
+++ b/tex/context/modules/mkii/s-mod-00.mkii
@@ -0,0 +1,511 @@
+%D \module
+%D [ file=s-mod-00,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Documentation Base Environment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module looks like crap, is not documented, will
+%D change, and used to be called modu-*.tex.
+
+% todo:
+%
+% file inclusions -> hyperlinks
+
+\mainlanguage[en] % better not here
+
+\usemodule[units]
+
+\enableactivediscretionaries
+\newprettytrue
+
+\unprotect
+
+% beter:
+%
+% group -> title
+% title -> category
+% subtitle -> subtitle
+
+% herzien ivm fonts
+
+% nog eens \interface \\ \\ verder doorvoeren
+
+\def\resetmoduledocumentation
+ {\getrawparameters
+ [Module]
+ [ file=\jobname,
+ type=,
+ version={\currentdate[\v!year,{.},\v!month,{.},\v!day]},
+ system=\CONTEXT,
+ title=Unknown Title,
+ subtitle=,
+ author=Unknown Author,
+ date=\currentdate,
+ copyright=Unknown Copyright,
+ suggestions=]}
+
+\resetmoduledocumentation
+
+\def\dostartmoduledocumentation[#1]%
+ {\newcounter\ParagraphNumber
+ \resetmoduledocumentation
+ \getrawparameters[Module][type=tex,#1]}
+
+\def\startmoduledocumentation
+ {\starttext
+ \dosingleempty\dostartmoduledocumentation}
+
+\def\stopmoduledocumentation
+ {\page
+ \placeregister
+ [\v!index]
+ [\c!balance=\v!yes,
+ \c!indicator=\v!no,
+ \c!criterium=\v!text]
+ \stoptext}
+
+% \def\complexmodule[#1]%
+% {\startglobal % i.v.m. \bgroup in \startdocumentation
+% \getrawparameters[Module][#1]
+% \stopglobal % i.v.m. \bgroup in \startdocumentation
+% \moduletitle}
+%
+% \def\simplemodule#1%
+% {\type{#1}}
+%
+% \definecomplexorsimple\module
+
+% \startmode[atpragma]
+%
+% \def\TitlePage#1% can be done more efficient
+% {\startMPrun
+% mpgraph := #1 ;
+% input mp-cont ;
+% \stopMPrun
+% \externalfigure
+% [\bufferprefix mprun.#1]
+% [\c!height=\vsize,
+% \c!width=\hsize]}
+%
+% \defineoverlay[titlepage][\TitlePage{512}]
+%
+% \stopmode
+
+\startuseMPgraphic{titlepage}
+
+ width := PaperWidth ;
+ height := PaperHeight ;
+
+ color local_red, local_white, local_blue ;
+
+ local_white := white ;
+
+ local_blue := local_white randomized (.6,.8) ;
+ local_red := local_white randomized (.3,.4) ;
+
+ u := width/400 ;
+
+ def a_module (expr dx, dy) =
+ picture p ; p := image
+ ( ddy := 0 ; sx := 60u ;
+ for i=1 upto (4 randomized 2) :
+ sy := 7u randomized 3u ;
+ fill unitsquare xyscaled(sx,sy) shifted (0,ddy)
+ withcolor local_red ;
+ ddy := ddy + sy + 4u ;
+ endfor ) ;
+ p := p shifted (dx,dy) shifted - center p ;
+ fill boundingbox p enlarged 8u withcolor local_white ;
+ fill boundingbox p enlarged 4u withcolor local_blue ;
+ draw p ;
+ enddef ;
+
+ set_grid(width, height, width/15, height/15) ;
+ forever:
+ if new_on_grid(uniformdeviate width,uniformdeviate height):
+ a_module(dx,dy) ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+
+ clip currentpicture to unitsquare xyscaled(width,height) ;
+\stopuseMPgraphic
+
+\defineoverlay
+ [titlepage]
+ [\useMPgraphic{titlepage}]
+
+\doifmode{atpragma}{\readfile{s-mod-04.tex}{}{}}
+
+\defineframed
+ [TitleFrame]
+ [\c!background=\v!color,
+ \c!backgroundcolor=white,
+ \c!align=\v!right,
+ \c!offset=12pt,
+ \c!strut=\v!no,
+ \c!frame=\v!off,
+ \c!bottom=]
+
+\definelayout
+ [titlepage]
+ [\c!backspace=0pt,
+ \c!topspace=0pt,
+ \c!header=0pt,
+ \c!footer=0pt,
+ \c!height=\v!middle,
+ \c!width=\v!middle]
+
+\def\moduletitle
+ {\setuplayout[titlepage]
+ \ifx\ModuleNumber\undefined \else
+ \ifnum\ModuleNumber<10
+ \edef\ModuleNumber{00\ModuleNumber}
+ \else\ifnum\ModuleNumber<100
+ \edef\ModuleNumber{0\ModuleNumber}
+ \fi\fi
+ \setupbackgrounds
+ [\v!page]
+ [\c!background=titlepage]
+ \fi
+ \startmakeup[\v!standard][\c!headerstate=\v!none,\c!footerstate=\v!none]
+ \switchtobodyfont[14.4pt,ss]
+ \bgroup
+ \def\CONTEXT {Con\kern-.15em\TeX t}
+ \def\TEXUTIL {\TeX Util}
+ \def\PPCHTEX {PPCH\TeX}
+ \def\METAPOST{MetaPost}
+ \hfill
+ {\definedfont[SansBold at 96pt]\setstrut
+ \TitleFrame{\Modulesystem}}
+ \vfill
+ \definetabulate[temp][|l|l|]%
+ \switchtobodyfont[17.3pt,ss]
+ \hfill
+ {\bf\setstrut
+ \TitleFrame
+ {\insidefloattrue\setuptabulate[\c!before=,\c!after=]%
+ \starttemp
+ \doifsomething{\Moduletitle}
+ {\NC title \EQ \Moduletitle \NC\NR}%
+ \doifsomething{\Modulesubtitle}
+ {\NC subtitle \EQ \Modulesubtitle \NC\NR}%
+ \doifsomething{\Moduleauthor}
+ {\NC author \EQ \Moduleauthor \NC\NR}%
+ \NC date \EQ \currentdate \NC\NR
+ %\doifsomething{\Modulesuggestions} % todo: generates space
+ % {\NC suggestions \NC \Modulesuggestions \NC\NR}%
+ \stoptemp}}
+ \egroup
+ \stopmakeup
+ \ifx\ModuleNumber\undefined \else
+ \setupbackgrounds
+ [\v!page]
+ [\c!background=]
+ \fi
+ \setuplayout}
+
+\let\stopdocumentation=\relax
+
+\def\startdocumentation
+ {\bgroup
+ \doglobal\newcounter\NOfMarginLines
+ \def\stopdocumentation{\par\egroup}}
+
+\newif\ifcompressdefinitions
+
+\def\startcompressdefinitions {\global\compressdefinitionstrue}
+\def\stopcompressdefinitions {\global\compressdefinitionsfalse}
+
+\gdef\CompressDefinitions%
+ {\ifcompressdefinitions
+ \switchtobodyfont[\v!small]%
+ \fi}
+
+\startnotmode[nocode]
+
+ \definetyping
+ [definition]
+
+ \setuptyping
+ [definition]
+ [\c!before={\page[\v!preference]}\blank\PresetParagraphNumber\CompressDefinitions,
+ \c!after=\ResetParagraphNumber\blank,
+ \c!option=\Moduletype]
+
+\stopnotmode
+
+\startmode[nocode]
+
+% \definieerbuffer[definition] % ignore
+
+ \long\def\startdefinition#1\stopdefinition{}
+
+\stopmode
+
+\definetyping [PL] [\c!option=PL, \c!margin=\v!standard]
+\definetyping [JV] [\c!option=JV, \c!margin=\v!standard]
+\definetyping [MP] [\c!option=MP, \c!margin=\v!standard]
+\definetyping [TEX] [\c!option=TEX,\c!margin=\v!standard]
+
+\setuptyping [\v!typing] [\c!margin=\v!standard]
+\setuptyping [\v!file] [\c!margin=\v!standard]
+\setuptyping [definition] [\c!margin=0pt]
+
+\newcounter\NOfMarginLines
+\newcounter\ParagraphNumber
+
+\def\ResetParagraphNumber
+ {\egroup}
+
+\def\PresetParagraphNumber
+ {\bgroup
+ \xdef\NOfTextLines%
+ {\the\prevgraf}%
+ \doglobal\decrement\NOfMarginLines
+ \doglobal\increment\ParagraphNumber
+ \message{.}%
+ \gdef\ShowParagraphNumber%
+ {\llap{\slx\ParagraphNumber\hskip\leftmargindistance}}%
+ \gdef\ShowParagraphNumberA%
+ {\ifnum\NOfMarginLines>\NOfTextLines\relax
+ \doglobal\increment\NOfTextLines
+ \else
+ \ShowParagraphNumber
+ \global\let\ShowParagraphNumberA=\relax
+ \global\let\ShowParagraphNumberB=\ShowParagraphNumber
+ \doglobal\newcounter\NOfMarginLines
+ \fi}%
+ \gdef\ShowParagraphNumberB%
+ {}%
+ \EveryLine
+ {\ShowParagraphNumberA}%
+ \EveryPar
+ {\vadjust{\nobreak}%
+ \ShowParagraphNumberB}}
+
+\EveryPar % skip one
+ {\EveryPar
+ {\doglobal\newcounter\NOfMarginLines}}
+
+\def\dodomargeaanduidingen[#1]#2%
+ {\def\docommand##1%
+ {\indent\hbox
+ {\ifx#2\relax
+ \index{##1}%
+ \else
+ \index{#2{##1}}%
+ \fi
+ #2{\doboundtext{##1}{\leftmarginwidth}{..}}}%
+ \doglobal\increment\NOfMarginLines
+ \endgraf}%
+ \processcommalist[#1]\docommand}
+
+\def\margeaanduidingen#1[#2]%
+ {\def\domargeaanduidingen##1##2%
+ {\margintitle[#2]%
+ {\switchtobodyfont[\v!small]%
+ \doglobal\newcounter\NOfMarginLines
+ \dodomargeaanduidingen[##1]#1%
+ \scratchcounter=\NOfMarginLines
+ \multiply\scratchcounter by 10
+ \divide\scratchcounter by 12
+ \advance\scratchcounter by 1
+ \xdef\NOfMarginLines{\the\scratchcounter}%
+ \processcommalist[##2]\index}}%
+ \dodoublegroupempty\domargeaanduidingen}
+
+\def\complexmacros{\margeaanduidingen\tex }
+\def\complexextras{\margeaanduidingen\relax}
+
+\def\complexelements
+ {\margeaanduidingen\someelement}
+
+\def\someelement#1{\type{<#1>}}
+
+\definecomplexorsimpleempty\macros
+\definecomplexorsimpleempty\extras
+\definecomplexorsimpleempty\elements
+
+\def\showelements{\dodoubleempty\doshowelements}
+
+\def\doshowelements[#1][#2]
+ {\bgroup
+ \processXMLbuffer
+ \typebuffer
+ \setupcolors[\c!state=\v!stop]
+ \showXSDcomponent[#1][#2]
+ \egroup}
+
+% \macros{a,b}
+% \macros{a,b}{b}
+% \macros[a]{a,b}{b}
+
+% weg ermee
+
+\defineparagraphs [interface] [\c!n=2]
+\setupparagraphs [interface] [1] [\c!width=4cm]
+
+\def\startexample{\par\startnarrower} \let\startvoorbeeld\startexample
+\def\stopexample {\stopnarrower} \let\stopvoorbeeld \stopexample
+
+\gdef\VisualizeLastSpace{\ifdim\lastskip>0pt\unskip\tttf\char32\fi}
+
+\gdef\ShowHeadText #1{\tttf#1\VL\mainlanguage[\currentlanguage]\headtext {#1}\VisualizeLastSpace}
+\gdef\ShowLabelText#1{\tttf#1\VL\mainlanguage[\currentlanguage]\labeltext{#1}\VisualizeLastSpace}
+
+\startbuffer[lang-a]
+\starttable[|l|l|]
+ \HL
+ \VL \bf head key \VL \bf current value \VL\SR
+ \HL
+ \VL \ShowHeadText \v!abbreviations \VL\FR
+ \VL \ShowHeadText \v!units \VL\MR
+ \VL \ShowHeadText \v!figures \VL\MR
+ \VL \ShowHeadText \v!graphics \VL\MR
+ \VL \ShowHeadText \v!index \VL\MR
+ \VL \ShowHeadText \v!content \VL\MR
+ \VL \ShowHeadText \v!intermezzi \VL\MR
+ \VL \ShowHeadText \v!logos \VL\MR
+ \VL \ShowHeadText \v!tables \VL\LR
+ \HL
+\stoptable
+\stopbuffer
+
+\startbuffer[lang-b]
+\starttable[|l|l|]
+ \HL
+ \VL \bf label key \VL \bf current value \VL\SR
+ \HL
+ \VL \ShowLabelText \v!table \VL\FR
+ \VL \ShowLabelText \v!figure \VL\MR
+ \VL \ShowLabelText \v!intermezzo \VL\MR
+ \VL \ShowLabelText \v!graphic \VL\MR
+ \VL \ShowLabelText \v!chapter \VL\MR
+ \VL \ShowLabelText \v!section \VL\MR
+ \VL \ShowLabelText \v!subsection \VL\MR
+ \VL \ShowLabelText \v!subsubsection \VL\MR
+ \VL \ShowLabelText \v!appendix \VL\MR
+ \VL \ShowLabelText \v!part \VL\MR
+ \VL \ShowLabelText \v!line \VL\MR
+ \VL \ShowLabelText \v!lines \VL\LR
+ \HL
+\stoptable
+\stopbuffer
+
+\startbuffer[lang-c]
+\starttable[|l|l|]
+ \HL
+ \VL \bf label key \VL \bf current value \VL\SR
+ \HL
+ \VL \ShowLabelText \v!january \VL\FR
+ \VL \ShowLabelText \v!february \VL\MR
+ \VL \ShowLabelText \v!march \VL\MR
+ \VL \ShowLabelText \v!april \VL\MR
+ \VL \ShowLabelText \v!may \VL\MR
+ \VL \ShowLabelText \v!june \VL\MR
+ \VL \ShowLabelText \v!july \VL\MR
+ \VL \ShowLabelText \v!august \VL\MR
+ \VL \ShowLabelText \v!september \VL\MR
+ \VL \ShowLabelText \v!october \VL\MR
+ \VL \ShowLabelText \v!november \VL\MR
+ \VL \ShowLabelText \v!december \VL\LR
+ \HL
+\stoptable
+\stopbuffer
+
+\startbuffer[lang-d]
+\starttable[|l|l|]
+ \HL
+ \VL \bf label key \VL \bf current value \VL\SR
+ \HL
+ \VL \ShowLabelText \v!sunday \VL\FR
+ \VL \ShowLabelText \v!monday \VL\MR
+ \VL \ShowLabelText \v!tuesday \VL\MR
+ \VL \ShowLabelText \v!wednesday \VL\MR
+ \VL \ShowLabelText \v!thursday \VL\MR
+ \VL \ShowLabelText \v!friday \VL\MR
+ \VL \ShowLabelText \v!saturday \VL\LR
+ \HL
+\stoptable
+\stopbuffer
+
+\gdef\ShowTextsValues[#1][#2]%
+ {\vbox\bgroup
+ \language[#1]%
+ \setbox\scratchbox\hbox to \hsize{\hss\bfb#2 language defaults\hss}
+ \dp\scratchbox\zeropoint
+ \box\scratchbox
+ \vskip1em
+ \hrule
+ \vskip2em
+ \halign
+ {\hss##\hss&##\hskip1em&\hss##\hss\cr
+ $\vcenter{\getbuffer[lang-a]}$&&$\vcenter{\getbuffer[lang-b]}$\cr
+ \noalign{\vskip1em}
+ $\vcenter{\getbuffer[lang-c]}$&&$\vcenter{\getbuffer[lang-d]}$\cr}%
+ \egroup}
+
+\gdef\ShowLanguageValues[#1][#2]#3#4%
+ {\hbox to \hsize
+ {\hss
+ \vbox
+ \bgroup
+ \language[#1]%
+ \let\normalbar=|
+ \starttable[||||]
+ \HL
+ \VL \THREE{\bf subsentence symbol and quotes} \VL\SR
+ \HL
+ \VL \quotation{#3 #4} \VL \quote{#2} \VL \let|=\normalbar |<||<|#3|>|#4|>| \VL\FR
+ \VL \quotation{#3 #4} \VL \quote{#2} \VL |<||<|#3|>|#4|>| \VL\LR
+ \HL
+ \stoptable
+ \egroup
+ \hss}}
+
+\gdef\doShowAllLanguageValues[#1][#2]#3#4%
+ {\vbox
+ {\ShowTextsValues[#1][#2]
+ \vskip2em
+ \ShowLanguageValues[#1][#2]{#3}{#4}}
+ \protect
+ \page}
+
+\gdef\ShowAllLanguageValues
+ {\page
+ \unprotect
+ \dodoubleargument\doShowAllLanguageValues}
+
+\protect
+
+%D Command references:
+
+% \input setupa
+% \input setupb
+
+\usemodule[int-load] \loadsetups
+
+\unprotect
+
+% \def\showsetup
+% {\doglobal\newcounter\CurrentArgument
+% \setup}
+
+\def\showsetup#1%
+ {{\def\y##1{\writestatus{setups}{warning: remove y! from #1}}%
+ \setup{#1}}}
+
+\setupframedtexts
+ [setuptext]
+ [\c!background=\v!screen,
+ \c!frame=\v!off]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/s-mod-01.mkii b/tex/context/modules/mkii/s-mod-01.mkii
new file mode 100644
index 000000000..5b83cd121
--- /dev/null
+++ b/tex/context/modules/mkii/s-mod-01.mkii
@@ -0,0 +1,155 @@
+%D \module
+%D [ file=s-mod-01,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Documentation Paper Environment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module looks like crap, is not documented, will
+%D change, and used to be called modu-*.tex.
+
+\usemodule[mod-00,abr-01]
+
+\dontcomplain
+
+\unprotect
+
+\setupbodyfont
+ [10pt]
+
+\definetypeface
+ [narrowtt] [tt]
+ [mono] [modern-cond] [default] [encoding=\defaultencoding]
+
+\setuptyping[\v!typing][\c!style=\narrowtt]
+\setuptype [\v!type] [\c!style=\narrowtt]
+
+\mainlanguage
+ [en]
+
+\setupwhitespace
+ [\v!big]
+
+\setuptolerance
+ [\v!verytolerant,\v!stretch]
+
+\setuplayout
+ [\c!backspace=3.5cm,
+ \c!leftmargin=1.75cm,
+ \c!rightmargin=0cm,
+ \c!margindistance=.5cm,
+ \c!leftedgedistance=.25cm,
+ \c!rightedgedistance=.5cm,
+ \c!edge=1.5cm,
+ \c!width=15.55333cm, % 13.998cm at 9pt => 15.55333 at 10pt
+ \c!topspace=2cm,
+ \c!header=1.25cm,
+ \c!footer=1.25cm,
+ \c!height=middle,
+ \c!style=\ss]
+
+\setupsetup
+ [\c!reference=1]
+
+\startnotmode[single]
+
+ \setuppagenumbering
+ [\c!alternative={\v!doublesided,\v!singlesided}]
+
+\stopnotmode
+
+\setuppagenumbering
+ [\c!location=]
+
+\expanded{\setupfootertexts
+ [\v!edge]
+ [][\v!pagenumber]}
+
+\startmode[single]
+
+ \setupfootertexts
+ [\v!margin]
+ [\filename{\Modulefile}][]
+
+\stopmode
+
+\startnotmode[single]
+
+ \setupfootertexts
+ [\v!margin]
+ [\filename{\Modulefile}][]
+ [\filename{\Modulefile}][]
+
+\stopnotmode
+
+\setupfootertexts
+ [\v!text]
+ [\CONTEXT]
+ [\Moduletitle]
+
+\setupheadertexts
+ [\v!text]
+ []
+ [\Modulesubtitle]
+
+\setupinmargin
+ [\c!location=\v!left]
+
+\setupheads
+ [\c!alternative=\v!inmargin]
+
+\setuphead
+ [\v!chapter]
+ [\c!style=\ssc,
+ \c!page=\v!right,
+ \c!header=\v!empty]
+
+\setuphead
+ [\v!section]
+ [\c!style=\ssb,
+ \c!page=\v!right]
+
+\setuplist
+ [\v!chapter]
+ [\c!style=\v!bold,
+ \c!after=\blank]
+
+\setupcombinedlist
+ [\v!content]
+ [\c!width=3em,
+ \c!aligntitle=\v!yes]
+
+\setupregister
+ [\v!index]
+ [\c!balance=\v!yes,
+ \c!indicator=\v!no]
+
+\startnotmode[nocolor]
+
+\setupcolors
+ [\c!state=\v!start]
+
+\stopnotmode
+
+\startnotmode[color]
+
+ \setupcolors
+ [\c!conversion=\v!always]
+
+ \setuptyping
+ [\c!palet=graypretty]
+
+\stopnotmode
+
+\setupinteraction
+ [\c!state=\v!start,
+ \c!color=,
+ \c!style=]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/s-mod-02.mkii b/tex/context/modules/mkii/s-mod-02.mkii
new file mode 100644
index 000000000..2d095ff9a
--- /dev/null
+++ b/tex/context/modules/mkii/s-mod-02.mkii
@@ -0,0 +1,421 @@
+%D \module
+%D [ file=s-mod-02,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Documentation Screen Environment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module looks like crap, is not documented, will
+%D change, and used to be called modu-*.tex.
+
+% Macro's
+
+\usemodule[mod-00]
+
+\unprotect
+
+% todo: internationalize + setups
+
+\setuphead[paragraaf][expansion=command]
+\setuphead[section][expansion=command]
+
+\def\complexmodule[#1]% redefined
+ {\startglobal % i.v.m. \bgroup in \startdocumentation
+ \getparameters[Module][#1]
+ \stopglobal % i.v.m. \bgroup in \startdocumentation
+ %%\section{\Modulesubtitle}
+ \xdef\Temp{\Modulesubtitle}%%Modulesubtitle:\framed{BEGIN \Modulesubtitle END} :#1 !}
+ \@EA\section\@EA{\Temp}
+ \WriteLists}
+
+\def\stopmodule % redefined
+ {\page
+ \determineregistercharacteristics
+ [index]
+ [criterium=section]
+ \doifmode{*register}
+ {\pagereference
+ [index]
+ \placeregister
+ [index]
+ [balance=yes,
+ indicator=no,
+ criterium=section]}}
+
+\let\ComposeLists=\relax
+
+\newcounter\ModuleNumber
+
+\newwrite\BatchFile \openout\BatchFile=\jobname.bat
+
+\def\WriteBatchFile
+ {\doglobal\increment\ModuleNumber
+% \immediate\write\BatchFile{call modu-run \FileName\space \ModuleNumber}}
+% \immediate\write\BatchFile{texmfstart texutil --modu \FileName}}
+ \immediate\write\BatchFile{texmfstart texexec --pdf --modu --batch \FileName }}
+
+\newif\ifProcessingPublic
+
+\def\WriteLists
+ {\writetolist[FileNames] {}{\FileName}
+ \writetolist[GroupItems]{}{\GroupItem}}
+
+\def\moduletitle{}
+
+\def\TypeZeroModule#1%
+ {\section{[to be extracted: #1]}
+ {\em This module is not yet split off.}
+ \WriteLists}
+
+\def\TypeOneModule#1%
+ {\section{[to be documented: #1]}
+ {\em This module is not yet fully documented.}
+ \WriteLists}
+
+\def\TypeTwoModule#1%
+ {\ifProcessingPublic
+ \readfile{#1.ted}{}{}%
+ \WriteBatchFile
+ \else
+ \section{[not yet public: #1]}
+ {\em This module is documented but not yet public.}
+ \WriteLists
+ \fi}
+
+\def\TypeThreeModule#1%
+ {\readfile{#1.ted}{}{}%
+ \WriteBatchFile}
+
+\def\processmodule#1#2%
+ {\page
+ \bgroup
+ \def\FileName{#1}
+ \setupreferencing[prefix=#1]
+ \useexternaldocument[PaperVersion][#1][]
+ \aftersplitstring#1\at-\to\GroupItem
+ \ComposeLists
+ \ifcase#2
+ \TypeZeroModule{#1}
+ \or
+ \TypeOneModule{#1}
+ \or
+ \TypeTwoModule{#1}
+ \or
+ \TypeThreeModule{#1}
+ \fi
+ \page
+ \setupreferencing[prefix=]
+ \egroup}
+
+\def\ModuleGroup#1#2%
+ {\page
+ \let\Modulefile=\empty
+ \setupreferencing[prefix=#1]
+ \def\FileGroup{#1}
+ \writetolist[FileGroups]{}{\FileGroup}
+ \chapter[content]{#2}
+ \MakeListOfItems
+ \MakeListOfNames
+ \MakeListOfGroups
+ \placecontent[criterium=chapter,level=section]}
+
+% Layout
+
+\setupbodyfont
+ [9pt]
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [backspace=72.5pt,
+ leftmargin=50pt,
+ leftmargindistance=12.5pt,
+ rightmargin=0pt,
+ rightedge=80pt,
+ rightedgedistance=10pt,
+ leftedge=0pt,
+ width=430pt,
+ topspace=10pt,
+ header=0pt,
+ footer=30pt,
+ bottomdistance=10pt,
+ bottom=15pt,
+ height=410pt,
+ style=\ss]
+
+\setuptyping
+ [palet=colorpretty]
+
+\setupsetup
+ [reference=3]
+
+\definecolor [AchtergrondKleur] [s=.6]
+\definecolor [ButtonKleur] [r=.2,g=.2,b=.6]
+\definecolor [TekstKleur] [r=.6,g=.2,b=.2]
+
+\definecolor [colorprettyone] [r=.6,g=.0,b=.0] % red
+\definecolor [colorprettytwo] [r=.0,g=.6,b=.0] % green
+\definecolor [colorprettythree] [r=.0,g=.0,b=.6] % blue
+\definecolor [colorprettyfour] [r=.6,g=.6,b=.0] % yellow
+
+\setupinteraction
+ [state=start,
+ page=yes,
+ contrastcolor=,
+ menu=on,
+ color=]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=AchtergrondKleur,
+ offset=2.5pt] % this offset influences the menus!
+
+\setupbackgrounds
+ [text,footer]
+ [text,leftmargin]
+ [background=color,
+ backgroundcolor=white]
+
+\setupsubpagenumber
+ [way=bysection,
+ state=start]
+
+\setupinteractionbar
+ [frame=off,
+ offset=0pt,
+ height=fit]
+
+\setupwhitespace
+ [big]
+
+\setuptyping
+ [typing]
+ [option=color]
+
+\setuptyping
+ [definition]
+ [option=color]
+
+\setuptyping
+ [file]
+ [option=color]
+
+\setuppagenumbering
+ [alternative=singlesided,
+ way=bysection,
+ state=none]
+
+\setupinmargin
+ [location=left]
+
+\setupheads
+ [alternative=inmargin]
+
+\setuphead
+ [chapter]
+ [style=\ssc,
+ page=right]
+
+\setuphead
+ [section]
+ [style=\ssb,
+ page=right]
+
+\setuplist
+ [chapter]
+ [style=bold,
+ after=\blank]
+
+\setupcontent
+ [width=2em]
+
+\setupindex
+ [balance=yes,
+ indicator=no]
+
+\setupcolors
+ [state=start]
+
+\def\TitelBlad#1%
+ {\startstandardmakeup
+ \definefont[GrootFont] [SansBold at 72pt]
+ \definefont[MiddelFont][Sans at 32pt]
+ \definefont[KleinFont] [Sans at 24pt]
+ \startcolor[AchtergrondKleur]
+ \vskip12pt
+ \midaligned{\GrootFont\setstrut\strut Con\TeX t}
+ \vskip24pt
+ \midaligned{\MiddelFont\setstrut\strut #1}
+ \vskip24pt
+ \midaligned{\KleinFont\setstrut\strut Hans Hagen}
+ \vfilll
+ \midaligned{\KleinFont\setstrut\strut PRAGMA ADE}
+ \vskip24pt
+ \midaligned{\KleinFont\setstrut\strut www.pragma-ade.com --- \currentdate}
+ \vskip12pt
+ \stopcolor
+ \stopstandardmakeup}
+
+\def\ColofonBlad
+ {\startmode[atpragma]
+ \page
+ \bgroup
+ \def\PragmaHoogte {\makeupheight}
+ \def\PragmaBreedte{\textwidth}
+ \def\PragmaKopwit {\topspace}
+ \def\PragmaRugwit {\backspace}
+ \def\PragmaMarge {0pt}
+ \PragmaLijnentrue
+ \PlaatsPragmaLogo[ADE]
+ \vfill
+ todo: colofon
+ \startnarrower[3*middle]
+ This is the official documentation of \CONTEXT\ version
+ \referraldate, a \TEX\ macropackage developed by J.~Hagen
+ \& A.F.~Otten, who both hold the copyrights.
+ \stopnarrower
+ \vfill
+ \page
+ \egroup
+ \stopmode}
+
+\def\ColofonBlad
+ {}
+
+\newbox\ListOfItems
+\newbox\ListOfGroups
+\newbox\ListOfNames
+
+\definelist[FileNames] \def\FileName {}
+\definelist[FileGroups] \def\FileGroup {}
+\definelist[GroupItems] \def\GroupItem {}
+
+\setuplist
+ [FileNames,FileGroups,FileGroups]
+ [expansion=yes,
+ pagenumber=no,
+ style=\ss\bf]
+
+\setuplist
+ [FileNames]
+ [command=\FileNameEntry,
+ after=\endgraf,
+ alternative=none] % horizontal
+
+\setuplist
+ [FileGroups]
+ [command=\FileGroupEntry,
+ after=\hss,
+ alternative=horizontal]
+
+\def\FileNameEntry#1#2#3%
+ {\strut\hbox{#2}\endgraf}
+
+\def\FileGroupEntry#1#2#3%
+ {\strut\hbox{#2}\endgraf}
+
+\def\MakeListOfItems
+ {\setbox\ListOfItems=\vbox
+ {\ss\bf
+ \placelist[GroupItems][color=ButtonKleur,contrastcolor=white,criterium=chapter]}}
+
+\def\MakeListOfNames
+ {\setbox\ListOfNames=\vbox
+ {\hsize\rightedgewidth
+ \ss\bf\setupinterlinespace
+ \startsimplecolumns[distance=10pt]
+ \placelist[FileNames][color=ButtonKleur,contrastcolor=white,criterium=chapter]
+ \stopsimplecolumns}}
+
+\def\MakeListOfGroups
+ {\setbox\ListOfGroups=\hbox to \textwidth
+ {\ss\bf
+ \setupinteraction[color=ButtonKleur]%
+ \placelist[FileGroups][color=ButtonKleur,contrastcolor=white,criterium=all]\unskip\unskip}}
+
+\setbox\ListOfGroups=\hbox{}
+
+%\setupfootertexts
+% [rand]
+% []
+% [{\interactiebalk[variant=g]}]
+
+\setupinteractionmenu
+ [right,bottom]
+ [state=start,
+ frame=off,
+ color=AchtergrondKleur,
+ contrastcolor=white,
+ style=\ss\bf,
+ height=15pt,
+ offset=0pt,
+ inbetween=\vskip5pt,
+ background=color,
+ backgroundcolor=ButtonKleur]
+
+\startinteractionmenu[right]
+ \boxofsize \vbox \textheight \footerdistance \footerheight 5pt
+ \bgroup
+ \copy\ListOfNames
+ \vfill
+ \but [\FileGroup:content] local contents \\
+ \but [\FileName:index] local register \\
+ \but [PaperVersion::begin] paper version \\
+ \but [content] main contents \\
+ \but [index] main register \\
+ \but [PreviousJump] previous jump \\
+ \but [CloseDocument] close document \\
+ \unskip
+ \egroup
+\stopinteractionmenu
+
+\startinteractionmenu[bottom]
+ \unhcopy\ListOfGroups
+\stopinteractionmenu
+
+\def\placemoduleregister
+ {\startbackmatter
+ \setupsubpagenumber[reset]
+ \title[-:index]{Register}
+ \placeregister[index]
+ \stopbackmatter}
+
+\def\placemodulecontent
+ {\startfrontmatter
+ \title[-:content]{Contents}
+ \setupinteractionbar[state=stop]
+ \placecontent[criterium=text,level=chapter]
+ \stopfrontmatter}
+
+\setupcontent
+ [pagenumber=no,
+ level=chapter,
+ interaction=all,
+ style=,
+ before=,
+ after=]
+
+\setupfootertexts
+ [margin]
+ [\tt\Modulefile]
+ []
+
+\setupfootertexts
+ [text]
+ [chapter][chapter]
+
+\setupindex
+ [symbol=1]
+
+\setuptolerance
+ [verytolerant]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/s-pre-17.mkii b/tex/context/modules/mkii/s-pre-17.mkii
new file mode 100644
index 000000000..7e8310a53
--- /dev/null
+++ b/tex/context/modules/mkii/s-pre-17.mkii
@@ -0,0 +1,399 @@
+%D \module
+%D [ file=s-pre-17,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 17,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setupbodyfont
+ [12pt,ss]
+
+\setupcolors
+ [state=start]
+
+\setupsystem
+ [random=medium]
+
+\setupbackgrounds
+ [state=repeat]
+
+\setupbackgrounds
+ [page]
+ [background={page,forward}]
+
+\setupbackgrounds
+ [text][text]
+ [background=blowup]
+
+\setupinteraction
+ [state=start,
+ %click=off,
+ color=TitleColor,
+ contrastcolor=TitleColor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+\definecolor [BackColor] [s=.30]
+\definecolor [PageColor] [g=1]
+\definecolor [FrameColor] [r=1]
+\definecolor [TitleColor] [y=1]
+\definecolor [ArrowColor] [b=1]
+
+\defineoverlay [title] [\useMPgraphic{title}]
+\defineoverlay [page] [\useMPgraphic{page}]
+\defineoverlay [blowup] [\overlaybutton{page(\realfolio)}]
+\defineoverlay [forward] [\overlaybutton{forward}]
+
+\startMPpositiongraphic{mppos:connection}
+ path pa, pb, pc ; pair ca, cb ;
+ initialize_box(\MPpos{\MPvar{self}}) ; pa := pxy ; ca := cxy ;
+ initialize_box(\MPpos{\MPvar{prev}}) ; pb := pxy ; cb := cxy ;
+ pickup pencircle scaled .5pt ;
+ pa := pa enlarged 10pt ;
+ pb := pb enlarged 10pt ;
+ for i=1 upto 10 :
+ draw pa randomized 20pt withcolor \MPcolor{FrameColor} ;
+ endfor ;
+ if \MPp{\MPvar{prev}}>0 :
+ pair a, b, c, d ;
+ for i=1 upto 25 :
+ a := .5[ulcorner pa,urcorner pa] randomized (10pt,10pt) ;
+ b := .5[llcorner pb,lrcorner pb] randomized (20pt,10pt) ;
+ c := .5[a,b] rotatedaround(a,-25) randomized (5pt,5pt) ;
+ d := .5[a,b] rotatedaround(a,+25) randomized (5pt,5pt) ;
+ draw (a--b) withcolor \MPcolor{ArrowColor} ;
+ draw (d--a--c) withcolor \MPcolor{ArrowColor} ;
+ endfor ;
+ fi ;
+ anchor_box(\MPanchor{\MPvar{self}}) ;
+\stopMPpositiongraphic
+
+\startuseMPgraphic{title}
+ pickup pencircle scaled .5pt ;
+ for i=1 upto 10 :
+ draw
+ fullsquare xyscaled(OverlayWidth,OverlayHeight)
+ enlarged 10pt randomized 20pt
+ withcolor \MPcolor{TitleColor} ;
+ endfor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled .5pt ;
+ fill Page withcolor \MPcolor{BackColor} ;
+ for i=1 upto 20 :
+ draw Page enlarged -50pt randomized 50pt withcolor \MPcolor{PageColor} ;
+ endfor ;
+ StopPage ;
+\stopuseMPgraphic
+
+\def\StartText%
+ {\bgroup
+ \getrandomdimen\scratchdimen{250pt}{350pt}%
+ \edef\TextWidth{\the\scratchdimen}%
+ \setbox\scratchbox=\hbox\bgroup
+ \hsize\TextWidth
+ \setupframedtexts
+ [before=,after=,
+ width=fit,align=right, % normal,
+ frame=off,foregroundcolor=white]%
+ \framedtext\bgroup}
+
+\def\BlowX{450pt} % \def\BlowX{600pt}
+\def\BlowY{300pt} % \def\BlowY{450pt}
+\def\BlowV {50pt} % \def\BlowV{100pt}
+\def\BlowH {75pt} % \def\BlowH{100pt}
+\def\BackO {50pt} % \def\BackO {50pt}
+
+\def\StopText%
+ {\egroup\egroup
+ \doglobal\increment\CurrentBlaBla
+ \let\PrevBlaBla\CurrentBlaBla \doglobal\decrement\PrevBlaBla
+ \let\NextBlaBla\CurrentBlaBla \doglobal\increment\NextBlaBla
+ \setMPpositiongraphic
+ {connection:\CurrentBlaBla}%
+ {mppos:connection}%
+ {seed=\CurrentBlaBla,
+ prev=connection:\PrevBlaBla,
+ next=connection:\NextBlaBla}%
+ \SetBlowUp{connection:\CurrentBlaBla}\BlowX\BlowY\BlowH\BlowV
+ \hbox to 600pt
+% {\getrandomdimen\scratchdimen{50pt}{100pt}%
+ {\getrandomdimen\scratchdimen{50pt}{75pt}%
+ \hskip0pt plus \scratchdimen minus \scratchdimen
+ \hpos{connection:\CurrentBlaBla}%
+ {\framed
+ [frame=off,
+ offset=overlay,
+ backgroundoffset=\BackO,
+ background=blowup]
+ {\box\scratchbox}}%
+% \getrandomdimen\scratchdimen{50pt}{100pt}%
+ \getrandomdimen\scratchdimen{50pt}{75pt}%
+ \hskip0pt plus \scratchdimen minus \scratchdimen}%
+% \getrandomdimen\scratchdimen{100pt}{150pt}%
+ \getrandomdimen\scratchdimen{75pt}{125pt}%
+ \vskip\scratchdimen
+ \egroup}
+
+\def\xStartText
+ {\bgroup
+ \setbox\scratchbox=\hbox\bgroup
+ \framed
+ [frame=off,foregroundcolor=white]
+ \bgroup}
+
+\def\xStopText{\StopText}
+
+\def\SetBlowUp#1#2#3#4#5% tag width height hoffset voffset
+ {\scratchdimen=\MPw{#1}%
+ \advance\scratchdimen-#2 %
+ \divide\scratchdimen by 2
+ \advance\scratchdimen by \MPx{#1}\relax
+ \ifdim\scratchdimen<0pt \scratchdimen=0pt \fi
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextX
+ \advance\scratchdimen by #2 %
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextW
+ %
+ \scratchdimen=\MPh{#1}%
+ \advance\scratchdimen-#3 %
+ \divide\scratchdimen by 2
+ \advance\scratchdimen\MPy{#1}\relax
+ \ifdim\scratchdimen<0pt \scratchdimen=0pt \fi
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextY
+ \advance\scratchdimen by #3
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextH
+ %
+ \def\PDFpageviewkey{ fitr \TextX\space\TextY\space\TextW\space\TextH}%
+ \def\PDFpageviewwrd{ /FitR \TextX\space\TextY\space\TextW\space\TextH}%
+ \edef\PDFpageview{/View [\PDFpageviewwrd]}}
+
+\def\xSetBlowUp#1#2#3#4#5% tag width height hoffset voffset
+ {\scratchdimen\MPx{#1}\relax
+ \ifdim\scratchdimen<#4
+ \ScaledPointsToBigPoints{0}\TextX
+ \multiply\scratchdimen 2
+ \else
+ \advance\scratchdimen-#4
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextX
+ \advance\scratchdimen#4
+ \advance\scratchdimen#4
+ \fi
+ \advance\scratchdimen\MPw{#1}%
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextW
+ %
+ \scratchdimen\MPy{#1}\relax
+ \ifdim\scratchdimen<#5
+ \ScaledPointsToBigPoints{0}\TextY
+ \multiply\scratchdimen 2
+ \else
+ \advance\scratchdimen-#5
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextY
+ \advance\scratchdimen#5
+ \advance\scratchdimen#5
+ \fi
+ \advance\scratchdimen\MPh{#1}%
+ \ScaledPointsToBigPoints{\number\scratchdimen}\TextH
+ %
+ \def\PDFpageviewkey{ fitr \TextX\space\TextY\space\TextW\space\TextH}%
+ \def\PDFpageviewwrd{ /FitR \TextX\space\TextY\space\TextW\space\TextH}%
+ \edef\PDFpageview{/View [\PDFpageviewwrd]}}
+
+\dontcomplain
+
+\def\StartPage#1%
+ {\doStartPage{1}{#1}}
+
+\def\doStartPage#1#2%
+ {\def\StopPage{\doStopPage{#1}{#2}}%
+ \setbox\scratchbox=\hbox\bgroup
+ \valign\bgroup\ignorespaces##\vss\cr}
+
+\def\doStopPage#1#2%
+ {\cr
+ \egroup
+ \egroup
+ \setbox\scratchbox=\vbox
+ {\vskip100pt
+ \hbox \ifcase#1 spread 200pt \else to \wd\scratchbox \fi
+ {\hss
+ \switchtobodyfont[big]%
+ \bfd\setupinterlinespace
+ \ifcase#1\else \SetBlowUp{title:\realfolio}\BlowX\BlowY\BlowH\BlowV \fi
+ \hpos{title:\realfolio}
+ {\framed
+ [frame=off,align=middle,
+ foregroundcolor=white,
+ background={title,blowup}]
+ {#2}}%
+ \hss}
+ \vskip100pt
+ \box\scratchbox}
+ \doFlushPage}
+
+\def\doFlushPage
+ {\scratchdimen=\ht\scratchbox
+ \advance\scratchdimen \dp\scratchbox
+ \advance\scratchdimen 100pt
+ \edef\height{\the\scratchdimen}
+ \scratchdimen=\wd\scratchbox
+ \advance\scratchdimen 100pt
+ \edef\width {\the\scratchdimen}
+ \expanded{\definepapersize[MASTER][width=\width,height=\height]}
+ \setuppapersize
+ [MASTER][MASTER]
+ \setuplayout
+ [topspace=25pt,backspace=25pt,
+ width=middle,header=0pt,footer=0pt,height=middle]
+ \centerbox{\box\scratchbox}
+ \page}
+
+\def\StartTopic#1%
+ {\unskip\unskip\cr
+ \doglobal\increment(\CurrentBlaBla,100)%
+ \vbox\bgroup
+ \vskip100pt
+ \bgroup
+ \definecolor[FrameColor][TitleColor]
+ \switchtobodyfont[big]
+ \bfd\setupinterlinespace
+ \xStartText#1\xStopText
+ \vskip25pt
+ \egroup}
+
+\def\StopTopic%
+ {\vskip-\lastskip
+ \vskip100pt
+ \egroup
+ \ignorespaces}
+
+\def\TitlePage#1%
+ {\doStartPage{0}{\def\\{\vskip1ex\bfc\def\\{\vskip1ex\bfb}}#1}
+ \StopPage}
+
+\doifnotmode{demo}{\endinput}
+
+\setupoutput[pdftex]
+
+\starttext
+
+\TitlePage{About Text\\Today's Talk\\Hans Hagen}
+
+\StartPage{The First Page}
+
+\StartTopic{Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+\StopTopic
+
+\StartTopic{Another Text}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+\StopTopic
+
+\StartTopic{Some More Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+\StopTopic
+
+\StartTopic{Some Text Agian}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+ \StartText \input tufte \StopText
+\StopTopic
+
+\StopPage
+
+\StartPage{The Second Page}
+
+\StartTopic{Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StartTopic{Another Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StartTopic{Some Nice Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input tufte \StopText
+\StopTopic
+
+\StartTopic{Some Funny Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+\StopTopic
+
+\StartTopic{Quite Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StartTopic{Even More Text}
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StopPage
+
+\StartPage{The Third Page}
+
+\StartTopic{Some Short Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StartTopic{Some Minimal Text}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+\StopTopic
+
+\StartTopic{Some More Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input tufte \StopText
+\StopTopic
+
+\StopPage
+
+\stoptext
diff --git a/tex/context/modules/mkii/s-pre-30.mkii b/tex/context/modules/mkii/s-pre-30.mkii
new file mode 100644
index 000000000..a7152deb6
--- /dev/null
+++ b/tex/context/modules/mkii/s-pre-30.mkii
@@ -0,0 +1,258 @@
+%D \module
+%D [ file=s-pre-30,
+%D version=2006.04.25,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 30,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[streams]
+
+\setuppapersize
+ [S6] [S6]
+
+\setupbodyfont
+ [12pt,tt]
+
+\definemeasure[bleed][6pt]
+
+\definecolor[maincolor-3][r=.5,g=.2,b=.2]
+\definecolor[maincolor-1][r=.2,g=.5,b=.2]
+\definecolor[maincolor-2][r=.2,g=.2,b=.5]
+
+\definecolor[pagecolor] [s=.5]
+\definecolor[resultcolor][s=1,t=.85,a=1]
+\definecolor[maincolor] [maincolor-3]
+
+\definecolorgroup
+ [maingroup]
+ [.5:.2:.2,
+ .2:.5:.2,
+ .2:.2:.5]
+
+\definecolorgroup
+ [resultgroup]
+ [1:.85:.85,
+ .85:1:.85,
+ .85:.85:1]
+
+\def\CurrentColor{1}
+
+\definecolor[maincolor] [maingroup:\CurrentColor]
+\definecolor[resultcolor][resultgroup:\CurrentColor]
+
+\def\NextColor{\ifnum\CurrentColor=3 \def\CurrentColor{1}\else\doglobal\increment\CurrentColor\fi}
+
+\setuplayout
+ [backspace=\measure{bleed},
+ topspace=30pt,
+ bottomdistance=\measure{bleed},
+ bottom=\dimexpr30pt-\measure{bleed}\relax,
+ header=0pt,
+ footer=0pt,
+ topdistance=\measure{bleed},
+ top=\dimexpr30pt-\measure{bleed}\relax,
+ width=middle,
+ height=middle]
+
+\setuptop
+ [before=\vfill,
+ after=\vfill,
+ strut=yes]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=\measure{bleed},
+ background=color,
+ backgroundcolor=maincolor]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=pagecolor]
+
+\setupcolors
+ [state=start,
+ textcolor=white]
+
+\setuphead
+ [chapter]
+ [style=\ttd]
+
+\setuphead
+ [section]
+ [style=\ttd]
+
+\defineproperty
+ [result]
+ [layer]
+ [state=stop]
+
+\definelayer
+ [result]
+
+\setuplayer
+ [result]
+ [width=\textwidth,
+ height=\textheight]
+
+\setupbackgrounds
+ [text]
+ [background={color,toggle,foreground,result}]
+
+\setupinteraction
+ [state=start,
+ click=no,
+ menu=on,
+ color=white,
+ contrastcolor=white,
+ closepageaction=HideLayer{result},
+ openpageaction=HideLayer{result}]
+
+% We add a dummy color switch so that each page has at least one
+% transparency; else acrobat will render the pages differently
+% bug in 6 and 7).
+
+\startinteractionmenu[bottom]
+% \color[resultcolor]{ }%
+ \hfill
+ \got [content] content \\
+ \got [previouspage] previous \\
+ \got [nextpage] next \\
+ \got [ToggleLayer{result}] result \\
+ \got [CloseDocument] close \\
+\stopinteractionmenu
+
+\setuphead
+ [section]
+ [placehead=no,
+ incrementnumber=list]
+
+\setuplist
+ [section]
+ [alternative=f]
+
+\defineoverlay
+ [toggle]
+ [\overlaybutton{ToggleLayer{result}}]
+
+\definestreamlayer
+ [resultstream]
+
+\startsetups streamlayer:resultstream:flush
+ \setlayer
+ [result]
+ [preset=middlebottom,
+ hoffset=\measure{bleed},
+% voffset=-\measure{bleed}]
+ voffset=\measure{bleed}]
+ {\startproperty[result]%
+% \framed
+% [offset=overlay,
+% frame=off,
+% background=color,
+% backgroundoffset=1\dimexpr\measure{bleed}\relax,
+% backgroundcolor=maincolor]
+ {\framed
+ [offset=overlay,
+ frame=off,
+ foregroundcolor=maincolor,
+ background=color,
+ backgroundoffset=1\dimexpr\measure{bleed}\relax,
+ backgroundcolor=resultcolor]
+ {\tightlayer[\currentstreamlayer]}}
+ \stopproperty}
+\stopsetups
+
+\startsetups show-definition
+ \subject{definition}
+ \typebuffer
+ \getbuffer
+ \page
+\stopsetups
+
+\startsetups show-result
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \getbuffer
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-usage
+ \subject{usage}
+ \typebuffer
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \getbuffer
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-usage-lines
+ \subject{usage}
+ \typebuffer
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \startlines
+ \getbuffer
+ \stoplines
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-contents
+ \startcolumns[n=3]
+ \placelist[section][criterium=text]
+ \stopcolumns
+ \pagereference[content]
+ \page
+ \NextColor
+\stopsetups
+
+\def\TitlePage#1%
+ {\title{#1}
+ \setups{show-contents}}
+
+\def\StartSample#1%
+ {\starttext
+ \page
+ \section{#1}
+ \setuptoptexts[][\processedfile\enspace:\enspace\lowercase{#1}]}
+
+\def\StopSample
+ {\page
+ \setuptoptexts[][]
+ \stoptext
+ \NextColor}
+
+\endinput
+
+\usemodule[pre-30]
+
+% \TitlePage{Howling to the moon}
+
+\StartSample{Basics}
+
+\startbuffer
+\lua{a = 1.5 ; b = 1.8 ; c = a*b ; tex.print(c) ;}
+
+\startlua
+ a = 1
+ b = 2
+ c = a*b
+ tex.print(c)
+\stoplua
+\stopbuffer
+
+\setups{show-usage}
+
+\StopSample
diff --git a/tex/context/modules/mkii/s-pre-60.mkii b/tex/context/modules/mkii/s-pre-60.mkii
new file mode 100644
index 000000000..8823c66ce
--- /dev/null
+++ b/tex/context/modules/mkii/s-pre-60.mkii
@@ -0,0 +1,143 @@
+%D \module
+%D [ file=s-pre-60,
+%D version=2004.03.15,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 60,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmode[paper,print]
+ \let\StartSteps\relax
+ \let\StopSteps \relax
+ \let\FlushStep \relax
+ \let\ResetStep \relax
+ \let\StartBusy\relax
+ \let\StopBusy \relax
+ \endinput
+\stopmode
+
+\newcounter\StepCounter
+\newcounter\StepMaximum
+
+\useJSscripts[stp]
+
+\startsetups[set-stepper]
+
+ \ifnum\getvariable{stepper}{nofsteps}>\StepMaximum
+
+ \dostepwiserecurse {\numexpr(\StepMaximum+1)} {\getvariable{stepper}{nofsteps}} {1}
+ {\doifnotmode{nosteps,nostep}
+ {\expanded{\defineproperty[step:\recurselevel][layer][state=stop,global=yes]}}}
+
+ \xdef\StepMaximum{\getvariable{stepper}{nofsteps}}
+
+ \fi
+
+\stopsetups
+
+\setvariables
+ [stepper]
+ [set=\setups{set-stepper},
+ nofsteps=50]
+
+\defineproperty[step:busy][layer][state=start,global=no]
+
+\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})]
+\definereference [ResetStepper] [JS(ResetStepper)]
+\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})]
+\definereference [InvokeStepper] [JS(InvokeStepper)]
+
+\def\ResetStep {\doglobal\newcounter\StepCounter}
+\def\NextStep {\doglobal\increment \StepCounter}
+\def\PrevStep {\doglobal\decrement \StepCounter}
+
+% todo: roll back blank
+
+\def\StepLayer {step:\StepCounter}
+\def\NextStepLayer {step:\the\numexpr\StepCounter+1\relax}
+\def\FirstStepLayer{step:1}
+
+\def\StartStep
+ {\ifvmode
+ \scratchskip\lastskip
+ \vskip-\scratchskip
+ \startproperty[\StepLayer]%
+ \vskip\scratchskip
+ \else
+ \startproperty[\StepLayer]%
+ \fi
+ \ignorespaces}
+
+\def\StopStep
+ {\removeunwantedspaces
+ \stopproperty}
+
+\def\StartSteps{\iftrialtypesetting\else\ResetStep\NextStep\StartStep\fi}
+\def\StopSteps {\iftrialtypesetting\else\StopStep \PrevStep \fi}
+\def\FlushStep {\iftrialtypesetting\else\StopStep \NextStep\StartStep\fi}
+
+\appendtoks
+ \ResetStep
+\to \everyaftershipout
+
+\def\StartBusy{\startproperty[step:busy]\ignorespaces}
+\def\StopBusy {\removeunwantedspaces\stopproperty}
+
+\setupinteraction
+ [%openaction=SetupStepper,
+ closeaction=ResetStepper,
+ openpageaction=CheckStepper,
+ closepageaction=ResetStepper]
+
+\defineoverlay[invoke][\overlaybutton{InvokeStepper}]
+
+\setupbackgrounds
+ [text]
+ [background=invoke]
+
+% bonus
+
+\useMPlibrary[nav]
+
+\definepalet
+ [navplus]
+ [attach=interactioncolor,
+ comment=interactioncolor]
+
+\setupcomment
+ [symbol={comment-normal,comment-down},
+ textlayer=\StepLayer,
+ option=buffer,
+ height=\textheight,
+ width=\textwidth,
+ margin=0pt]
+
+\setupattachments
+ [symbol={attach-normal,attach-down},
+ textlayer=\StepLayer]
+
+%D Handy:
+
+\def\StartLocalSteps{\ResetStep}
+\def\StopLocalSteps {}
+
+\def\StartLocalStep {\NextStep\StartStep}
+\def\StopLocalStep {\StopStep}
+
+%D used as (given some definitions):
+%D
+%D \starttyping
+%D \StartLocalSteps
+%D \startcombination[both]
+%D {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {}
+%D {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {}
+%D \stopcombination
+%D \StopLocalSteps
+%D \stoptyping
+
+\endinput
diff --git a/tex/context/modules/mkii/s-pre-71.mkii b/tex/context/modules/mkii/s-pre-71.mkii
new file mode 100644
index 000000000..343136768
--- /dev/null
+++ b/tex/context/modules/mkii/s-pre-71.mkii
@@ -0,0 +1,213 @@
+% engine=luatex
+
+%D \module
+%D [ file=s-pre-71,
+%D version=2008.08.05,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 71,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D I might improve this module so consider it experimental.
+
+% \enablemode[numbers]
+% \enablemode[paper]
+
+\usemodule[pre-60,abr-02]
+
+\setupinteraction[state=start,click=off]
+
+\definepapersize[wide][width=900pt,height=600pt]
+
+\setuppapersize[wide][wide]
+
+\setuplayout[page]
+
+% \setupbodyfont[15pt]
+
+\usetypescriptfile[type-hgz]
+\usetypescript[palatino-informal]
+\setupbodyfont[palatino-informal,15pt]
+
+\setupsorting[logo][style=]
+
+\startnotmode[paper]
+ \setupbackgrounds[page][background=color,backgroundcolor=black]
+\stopnotmode
+
+\TransparencyHack
+
+\definelayer[page][width=\paperwidth,height=\paperheight]
+
+\definecolor[TopicColor-1][r=.3,g=.4,b=.5]
+\definecolor[TopicColor-2][r=.3,g=.5,b=.4]
+\definecolor[TopicColor-3][r=.4,g=.3,b=.5]
+\definecolor[TopicColor-4][r=.4,g=.5,b=.3]
+\definecolor[TopicColor-5][r=.5,g=.3,b=.4]
+\definecolor[TopicColor-6][r=.5,g=.4,b=.3]
+\definecolor[TopicColor-7][r=.35,g=.35,b=.6]
+\definecolor[TopicColor-8][r=.6,g=.35,b=.35]
+\definecolor[TopicColor-9][r=.35,g=.6,b=.35]
+
+\definecolor[TopicColor-0][t=.5,a=1,s=.5]
+\definecolor[TopicColor] [s=1]
+
+\setupcolors[state=start]
+\setupcolors[textcolor=TopicColor]
+
+\startluacode
+ local locations = {
+ 'lefttop',
+ 'middletop',
+ 'righttop',
+ 'middleleft',
+ 'middle',
+ 'middleright',
+ 'leftbottom',
+ 'middlebottom',
+ 'rightbottom',
+ }
+ local done, current, previous, n = table.tohash(locations,false), 0, 0, 0
+ function document.reset_locations()
+ done, current, previous, n = table.tohash(locations,false), 0, 0, 0
+ end
+ function document.next_location(loc)
+ previous = current
+ n = n + 1
+ loc = loc and loc ~= "" and tonumber(loc)
+ while true do
+ current = loc or math.random(1,#locations)
+ if not done[current] then
+ done[current] = true
+ break
+ end
+ end
+ end
+ function document.current_location()
+ tex.print(locations[current] or "")
+ end
+ function document.previous_location()
+ tex.print(locations[previous] or "")
+ end
+ function document.current_n()
+ tex.print(tostring(current))
+ end
+ function document.previous_n()
+ tex.print(tostring(previous))
+ end
+ function document.step()
+ tex.print(tostring(n))
+ end
+\stopluacode
+
+\def\StartTopics
+ {\startstandardmakeup
+ \ctxlua{document.reset_locations()}
+ \doifnotmode{paper}{\StartLocalSteps}}
+
+\def\StopTopics
+ {\doifnotmode{paper}{\StopLocalSteps}
+ \flushlayer[page]
+ \stopstandardmakeup}
+
+\def\StartTopic
+ {\dosingleempty\doStartTopic}
+
+\def\doStartTopic[#1]%
+ {\doifnotmode{paper}{\NextStep}
+ \ctxlua{document.next_location("#1")}
+ \startnotmode[paper]
+ \doifnothing{#1}
+ {\ifcase\ctxlua{document.previous_n()}\else
+ \setlayer
+ [page]
+ [preset=\ctxlua{document.previous_location()}]
+ \bgroup
+ \doifnotmode{paper}{\startproperty[\StepLayer]}%
+ \framed
+ [offset=20pt,
+ strut=no,
+ align=normal,
+ frame=off,
+ height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ background=color,
+ backgroundcolor=TopicColor-0]
+ {}%
+ \doifnotmode{paper}{\stopproperty}%
+ \egroup
+ \fi}
+ \stopnotmode
+ \setlayer
+ [page]
+ [preset=\ctxlua{document.current_location()}]
+ \bgroup
+ \doifnotmode{paper}{\startproperty[\StepLayer]}%
+ \framed
+ [offset=20pt,
+ strut=no,
+ align=\expdoifelse{#1}{}{normal}{middle,lohi},
+ align=\expdoifelse{#1}{}{flushleft,verytolerant}{middle,lohi},
+ frame=off,
+ height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ background=color,
+ backgroundcolor=TopicColor-\ctxlua{document.current_n()}]
+ \bgroup
+ \ignorespaces}
+
+\def\StopTopic
+ {\removeunwantedspaces
+ \egroup
+ \doifnotmode{paper}{\stopproperty}%
+ \egroup
+ \startmode[numbers]
+ \setlayerframed
+ [page]
+ [preset=\ctxlua{document.current_location()}]
+ [height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ frame=off,
+ foregroundstyle=\bfa,
+ align={flushright,low}]
+ {\doifnotmode{paper}{\startproperty[\StepLayer]}%
+ \ctxlua{document.step()}\kern\strutdepth
+ \doifnotmode{paper}{\stopproperty}}
+ \stopmode}
+
+\logo [METAPOST] {MetaPost}
+
+\definefont[TitleFont][SansBold at 60pt]
+\definefont[TempFont] [SansBold at 12pt]
+
+\let\StartText\starttext
+\let\StopText \stoptext
+
+\doifnotmode{demo}{\endinput}
+
+\starttext
+
+\StartTopics
+ \StartTopic[1] A \StopTopic
+ \StartTopic[5] B \StopTopic
+ \StartTopic[9] C \StopTopic
+\StopTopics
+
+\StartTopics
+ \StartTopic A \StopTopic
+ \StartTopic B \StopTopic
+ \StartTopic C \StopTopic
+ \StartTopic D \StopTopic
+ \StartTopic E \StopTopic
+ \StartTopic F \StopTopic
+ \StartTopic G \StopTopic
+ \StartTopic H \StopTopic
+ \StartTopic I \StopTopic
+\StopTopics
+
+\stoptext
diff --git a/tex/context/modules/mkii/s-ptj-01.mkii b/tex/context/modules/mkii/s-ptj-01.mkii
new file mode 100644
index 000000000..a14a03ef1
--- /dev/null
+++ b/tex/context/modules/mkii/s-ptj-01.mkii
@@ -0,0 +1,425 @@
+%D \module
+%D [ file=s-ptj-01,
+%D version=2009.12.18,
+%D title=\CONTEXT\ Style File,
+%D subtitle=PracTeX Journal Style,
+%D author=Aditya Mahajan,
+%D email=adityam at umich dot edu,
+%D date=\currentdate,
+%D copyright={Aditya Mahajan}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%M % These macros are needed to compile the documentation.
+%M \def\PracTeX {Prac\kern-0.07em\TeX}
+%M \def\PRACTEX {\PracTeX}
+%M \def\pracjourn {The \PRACTEX\ Journal}
+%M \useurl[pracjourn][http://www.tug.org/pracjourn/][][\pracjourn]
+%M \useurl[texgyre] [http://www.gust.org.pl/projects/e-foundry/tex-gyre/]
+
+\writestatus {loading} {Context Module for the PracTeX Journal}
+
+%D This module is for producing acticles for \from[pracjourn]. It merely copies the
+%D layout of the the \LATEX\ class \filename{pracjourn.cls} available from
+%D \pracjourn\ website (\url[pracjourn]). This module has a filename synonym
+%D \filename{pracjourn}. So to use this module, you can write:
+%D \starttyping
+%D \usemodule[pracjourn]
+%D \stoptyping
+%D A sample document is given at the end of this file. The typeset sample can
+%D be obtained by
+%D \starttyping
+%D texmfstart texexec --mode=demo s-ptj-01.tex
+%D \stoptyping
+%D The documentation is written as comments. If you want to see a \PDF\ copy
+%D \starttyping
+%D texmfstart texexec --module s-ptj-01.tex
+%D \stoptyping
+
+\startmodule[pracjourn]
+
+\unprotect
+
+%D First let's setup the paper size and layout for \pracjourn. I am actually not
+%D sure about the \quote{official} layout requirement for \pracjourn\ and have
+%D reverse engineered the layout from the typeset \LATEX\ examples. If you
+%D feel that anything is wrong here, please let me know.
+
+\setuppapersize
+ [letter][letter]
+
+\setuplayout
+ [ width=middle,
+ height=middle,
+ location=middle,
+ topspace=1.25in,
+ bottomspace=1in,
+ backspace=1in,
+ cutspace=1in,
+ leftmargin=0.25in,
+ rightmargin=0.25in,
+ leftmargindistance=0in,
+ rightmargindistance=0in,
+ header=1in,
+ footer=.5in,
+ headerdistace=0in,
+ footerdistance=.25in,
+ ]
+
+%D Next we do the font setup. \pracjourn\ uses mathpazo for roman and math faces and
+%D uses latin modern for sans serif and monotype. For the main face, 12pt is
+%D used with a 15.5pt baseline skip. Font protrusion is enabled, but font
+%D expansion is not. We follow these conventions. \CONTEXT\ uses Pagella fonts
+%D from \TEX{gyre} project, so we use them instead.
+
+\usetypescript [serif,sans,mono] [hanging] [pure]
+\setupalign [hanging]
+\usetypescript [palatino][encoding=texnansi]
+\setupbodyfont [palatino,12pt]
+
+\definefont [titlefont] [Regular at 20pt]
+\definefont [authorfont] [Regular at 14pt]
+
+\setupbodyfontenvironment
+ [12pt]
+ [interlinespace=15.5pt,em=italic]
+
+\setupbodyfontenvironment
+ [11pt]
+ [interlinespace=13.6pt,em=italic]
+
+%D The variables for the article are stored in the \mono{pracjourn} namespace.
+%D To initialize these variables use
+%D \starttyping
+%D \setvariables
+%D [pracjourn]
+%D [ title=Tile of the Article,
+%D author=Name of Author,
+%D address=Write your Address,
+%D revision={d=14,m=11,y=2006},
+%D copyright=Whatever you want,
+%D ]
+%D \stoptyping
+%D \mono{title} and \mono{author} should always be entered (even though this
+%D module does not make them mandatory, it makes little sense to have an
+%D article without a title or author. Other variables are optional. If a
+%D revision is not written, current date will be used to show the revision.
+%D Other variables for the article are the author's email address and website
+%D url. Due to catcode problems, it is not always possible to reliably enter
+%D these using the variable mechanism. To enter these use \type|\useURL|
+%D \starttyping
+%D \useURL[email][mailto:address@whatever.com][][address@whatever.com]
+%D \useURL[website][link to your homepage]
+%D \stoptyping
+%D If either of these \URL's are not present, they will be silently ignored
+%D while generating the title.
+
+\setvariables [pracjourn] [ title=]
+\setvariables [pracjourn] [ author=]
+\setvariables [pracjourn] [ address=]
+\setvariables [pracjourn] [copyright=]
+\setvariables [pracjourn] [ revision=]
+
+%D We use the buffer \filename{abstract} for the abstract. So to enter the
+%D abstract, write
+%D \starttyping
+%D \startbuffer[abstract]
+%D Write your abstract
+%D \stopbuffer
+%D \stoptyping
+%D Right now, there is no mechanism to inhibt abstracts. In case someone
+%D requires it, such a mechanism is easy to implement.
+
+\startbuffer[abstract]
+\stopbuffer
+
+%D The actual title with the additional information is typset by calling
+%D \starttyping
+%D \setups{title}
+%D \stoptyping
+%D Remember that the \type|\setvariables[pracjourn][...]| step must be done
+%D before \type|\setups{title}|.
+
+\setuphead
+ [title]
+ [style=\titlefont,
+ after={\blank[big]}]
+
+%D Next we define internal frames to take care of the layout of the extra
+%D material in the title.
+
+\defineframed
+ [pracjourninfotitle]
+ [ frame=off,
+ strut=yes,
+ width=0.1\textwidth,
+ height=fit,
+ align=left,
+ location=hanging,
+ ]
+
+\defineframed
+ [pracjourninfodetails]
+ [ frame=off,
+ strut=yes,
+ width=0.85\textwidth,
+ height=fit,
+ align=normal,
+ location=hanging,
+ ]
+
+\newif\ifpracjourntitleskipdone
+
+\def\pracjourninfo#1#2%
+ {\pracjourntitleskipdonetrue
+ \hbox to \textwidth
+ \bgroup
+ \hfill \pracjourninfotitle{#1}
+ \hfill \pracjourninfodetails{#2}
+ \egroup\endgraf}
+
+%D Now we take care of the actual layout of the title. Most of this is
+%D heuristic, as I was trying to get the same visual effect as the
+%D \filename{pracjourn.cls} class. If something does not match, please let me
+%D know. The information is typeset as
+%D \starttyping
+%D \hfill <box of .1\textwidth> \hfill <box of .85\textwidth>
+%D \stoptyping
+%D at 11pt size. We also add the title and author information in the \PDF\
+%D metadata.
+
+\startsetups [title]
+% Place the tile and the author
+ \title{\getvariable{pracjourn}{title}}
+ \blank[medium]
+ \bgroup\authorfont\setupinterlinespace
+ \getvariable{pracjourn}{author} \endgraf\egroup
+ \blank[2*big]
+% Place the additional information
+ \bgroup\switchtobodyfont[11pt]
+ \setupindenting[no]
+ \doifurldefinedelse{email}
+ {\pracjourninfo{Email}{\tttf\from[email]\relax}}
+ \empty
+ \doifurldefinedelse{website}
+ {\pracjourninfo{Website}{\from[website]\relax}}
+ \empty
+ \doifsomething{\getvariable{pracjourn}{address}}
+ {\pracjourninfo{Address}{\getvariable{pracjourn}{address}}}
+ \ifpracjourntitleskipdone \blank[big] \fi
+ \pracjourninfo{Abstract}
+ {\setupindenting[yes]
+ \setupinterlinespace
+ \getbuffer[abstract]
+ \endgraf}
+ \egroup
+ \blank[big]
+ \setups{pracjourndate}
+ % Add information to pdfmetadata
+ \setupinteraction
+ [title={\getvariable{pracjourn}{title}},
+ author={\getvariable{pracjourn}{author}},
+ subtitle={The PracTeX Journal Article}]
+\stopsetups
+
+% If revision number is present, write it to \filename{_rev.tex}
+% FIXME: Do we need to ensure that the dates and month are two digits?
+\startrawsetups [pracjourndate]
+ \doifsomething{\getvariable{pracjourn}{revision}}
+ {\expanded{\setvariables[pracjourn:date][y=,m=,d=,\getvariable{pracjourn}{revision}]}
+ \immediate\openout \scratchwrite _rev.tex
+ \immediate\write \scratchwrite
+ {\getvariable{pracjourn:date}{y}/\getvariable{pracjourn:date}{m}/\getvariable{pracjourn:date}{d}}
+ \immediate\closeout\scratchwrite}
+\stoprawsetups
+
+%D Next we setup the header and footer for the first page. \pracjourn\ formats the
+%D header as
+%D \startlines
+%D The PracTeX Journal, year, No. number
+%D Article revision year/mm/dd
+%D \stoplines
+%D If a copyright notice is present, it is printed right aligned on the bottom
+%D of first page. Otherwise the footer on the first page is empty.
+
+\startsetups [pracjourntitleheader]
+ \framed[frame=off,width=\textwidth,align=normal,location=low]
+ {\small\setupinterlinespace
+ \doifelsenothing{\pracjournissue}
+ {For submission to \pracjourn}
+ {\pracjournissue}
+ \endgraf
+ \doifelsenothing{\getvariable{pracjourn}{revision}}
+ {Draft of \currentdate[year,/,mm,/,dd]}
+ {Article revision\space
+ \expanded{\date[\getvariable{pracjourn}{revision}][year,/,mm,/,dd]}}
+ \endgraf}
+\stopsetups
+
+\startsetups [pracjourntitlefooter]
+ \framed[frame=off,width=\textwidth,align=flushright,location=low]
+ {\small\setupinterlinespace \getvariable{pracjourn}{copyright}\endgraf}
+\stopsetups
+
+\definetext [pracjourntitleheader] [header] [\setups{pracjourntitleheader}][]
+\definetext [pracjourntitlefooter] [footer] [\setups{pracjourntitlefooter}]
+
+\setuphead
+ [title]
+ [header=pracjourntitleheader,
+ footer=pracjourntitlefooter]
+
+%D For rest of the pages, page number is printed on the middle of the footer.
+
+\setuppagenumbering [location={footer,middle}, style=mediaeval]
+
+%D Next we setup the formating for the sections. \pracjourn\ wants font sizes of
+%D 17pt, 14pt, and 12pt respectively for section, subsection, and
+%D subsubsection. By default, \tex{tfa} is 1.2, \tex{tfb} is 1.4, so the sizes
+%D come out close to what is required. The section number is typset in
+%D oldstyle fonts.
+
+\setuphead
+ [section,subject]
+ [ style=\tfb,
+ numberstyle=mediaeval,
+ before={\blank[2*big]},
+ after={\blank[big]},
+ ]
+
+\setuphead
+ [subsection,subsubject]
+ [ style=\tfa,
+ numberstyle=mediaeval,
+ before={\blank[big]},
+ after={\blank[medium]},
+ ]
+
+\setuphead
+ [subsubsection,subsubsubject]
+ [ style=\tf,
+ numberstyle=mediaeval,
+ before={\blank[medium]},
+ after={\blank},
+ ]
+
+%D Now we setup the captions. The captions head are set in normal font, and
+%D the caption number is set in oldstlyle.
+
+\setupcaptions [headstyle=normal,stopper=:,conversion=mediaeval]
+
+%D Footnotes are placed in a box with a width of 1.5em. The footnote numeral
+%D are set in oldstyle font.
+
+\setupnote
+ [footnote]
+ [margindistance=0em,
+ conversion=mediaeval,
+ command=\pracjournfootnote,
+ ]
+
+\setupnotedefinition [footnote] [location=left,hang=1]
+
+\def\pracjournfootnote#1{\hbox to 1.5em{#1.}}
+
+%D \pracjourn\ uses dash as the first level of itemize and text period as the second
+%D level. The third level is left unspecified.
+
+\definesymbol [1] [{\symbol[dash]}]
+\definesymbol [2] [\periodcentered]
+
+\setupitemize [each] [packed]
+\setupitemize [1] [packed,autointro] [margin=1em]
+
+%D We enable colors, interaction and bookmarks.
+
+\setupinteraction [state=start,color=darkred,style=normal]
+\setupurl [color=darkred]
+\setupcolors [state=start]
+\placebookmarks [section,subsection] [section]
+
+%D We setup medium indenting, whitespace and blanks.
+
+\setupindenting [medium,yes]
+\setupwhitespace [medium]
+\setupblank [medium]
+
+%D We define logos for \PRACTEX\ and \pracjourn. These definitions are copied from
+%D \filename{pracjourn.cls} and can be accessed by \type|\PracTeX|,
+%D \type|\PRACTEX| and \type|\pracjourn|.
+
+\def\PracTeX{Prac\kern-0.07em\TeX}
+\def\PRACTEX{\PracTeX}
+\def\pracjourn {The \PRACTEX\ Journal}
+
+%D \filename{pracjourn.cls} provides two macros \type|\ctanfile| and
+%D \type|\ctanloc|. I am not sure what is the advantage of these macors. If
+%D you want to use these macros, you can use the \type|\useURL| mechanism of
+%D \CONTEXT. For example
+%D \starttyping
+%D \useURL[pracjourn][http://ctan.org/get?fn=/macros/contrib/latex/pracjourn][][\mono{CTAN:macros/contrib/latex/pracjourn}]
+%D The \LATEX\ style files for \pracjourn\ is localed at \from[pracjourn]
+%D \stoptyping
+
+%D For the final version of the paper, the string \quotation{The PracTeX
+%D Journal year, No x} is written on the header. This only happens when the
+%D current directory contains a file \filename{_iss.tex} which contains string
+%D like \quotation{pracjourn 2006 No 04, 2006-11-15}. This step is usually taken in
+%D the final production of the article. If this file is absent, \quotation{For
+%D submission to the PracTeX Journal} is written instead. The next macros are
+%D used to parse this file.
+
+\let\pracjournissue\empty
+
+\def\parse@iss pracjourn #1 No #2, #3-#4-#5\@nil%
+ {\!!counta#2\relax
+ \edef\pracjournissue{\pracjourn, #1, No.\,\the\!!counta}}
+
+%D Read the \filename{_iss.tex} file, if present to determine the current
+%D issue.
+
+\immediate\openin\scratchread _iss.tex
+\ifeof\scratchread\else
+ \read \scratchread to \!!stringa
+ \expandafter\parse@iss\!!stringa\@nil
+\fi
+\immediate\closein\scratchread
+
+\protect
+
+\stopmodule
+
+\doifnotmode{demo}{\endinput}
+
+\usemodule[pracjourn]
+
+\setvariables
+ [pracjourn]
+ [ title=\PRACTEX\ Article in \CONTEXT,
+ author=Aditya Mahajan,
+ address={Ann Arbor,\\ Michigan, USA.},
+ revision={y=2006,m=11,d=14},
+ copyright={Copyright \copyright\ 2006 Aditya Mahajan.}
+ ]
+
+\useURL[website][http://www.eecs.umich.edu/~adityam]
+\useURL[email][mailto:adityam@umich.edu][][adityam@umich.edu]
+
+%D If any of the above information is not provided, the corresponding entry
+%D will not apprear in the title.
+
+\startbuffer[abstract]
+Write abstract here
+\stopbuffer
+
+\starttext \setups[title]
+
+\section{Introduction}
+
+Write your article \unknown
+
+\stoptext
+
+\endinput
diff --git a/tex/context/modules/mkii/s-syntax.mkii b/tex/context/modules/mkii/s-syntax.mkii
new file mode 100644
index 000000000..6d1d59697
--- /dev/null
+++ b/tex/context/modules/mkii/s-syntax.mkii
@@ -0,0 +1,54 @@
+%D \module
+%D [ file=s-syntax, % was: s-syn-01,
+%D version=0000.00.00,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Preliminary Syntax Stuff,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is needed for the \METAFUN\ manual (this module was
+%D called \type {p-syn-01} on my machine).
+
+\unprotect
+
+\def\Indent #1{\ifvmode\noindent\hbox to 2em{\hss#1}\else#1\fi}
+\def\Sugar #1{\ifhmode\unskip\unskip\unskip\fi\kern.25em{#1}\kern.25em\ignorespaces}
+\def\Something#1{\Sugar{\mathematics{\langle\hbox{#1}\rangle}}}
+\def\Lbrace {\Sugar{\tttf\leftargument}}
+\def\Rbrace {\Sugar{\tttf\rightargument}}
+\def\Or {\Sugar{\mathematics{\vert}}}
+\def\Optional #1{\Sugar{\mathematics{[\hbox{#1}]}}}
+\def\Means {\Sugar{\mathematics{\rightarrow}}}
+\def\Tex #1{\Sugar{\type{#1}}}
+\def\Literal #1{\Sugar{\type{#1}}}
+\def\Syntax #1{\strut\kern-.25em{#1}\kern-.25em}
+\def\Next {\crlf\hbox to 2em{}\nobreak}
+\def\Whatever #1{\Sugar{\mathematics{(\hbox{#1})}}}
+\def\Quote #1{\Sugar{\quote{#1}}}
+
+\def\Or {\Sugar{\Indent{\mathematics{\vert}}}}
+\def\Means {\Sugar{\Indent{\mathematics{\rightarrow}}}}
+
+\def\StartSyntax
+ {\goodbreak
+ \startlines
+ \catcode`\#=12
+ \let\L \Literal
+ \let\S \Something
+ \def\FL##1{\color[darkred]{\L{##1}}}
+ \def\FS##1{\S{\color[darkred]{##1}}}
+ \let\M \Means
+ \let\O \Or
+ \let\Q \Quote
+ \let\LB\Lbrace
+ \let\RB\Rbrace}
+
+\def\StopSyntax
+ {\stoplines}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-calcmath.mkii b/tex/context/modules/mkii/x-calcmath.mkii
new file mode 100644
index 000000000..a649aa648
--- /dev/null
+++ b/tex/context/modules/mkii/x-calcmath.mkii
@@ -0,0 +1,24 @@
+%D \module
+%D [ file=m-calcmath,
+%D version=2006.04.24, % 1999.11.06,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Calculator Math,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\writestatus{calcmath}{this is not supported in mkii}
+
+\let\inlinecalcmath \inlinemathematics
+\def\displaycalcmath \displaymathematics
+\let\calcmath \inlinecalcmath
+\let\icm \inlinecalcmath
+\let\dcm \displaycalcmath
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-chemml.mkii b/tex/context/modules/mkii/x-chemml.mkii
new file mode 100644
index 000000000..08d64e54b
--- /dev/null
+++ b/tex/context/modules/mkii/x-chemml.mkii
@@ -0,0 +1,212 @@
+%D \module
+%D [ file=m-chemml,
+%D version=2001.09.12,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Loading CHEMML Filters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\useXMLfilter[cml]
+
+%D Structural formulas are codes in a \PPCHTEX\ way; this
+%D will change -)
+%D
+%D \startbuffer
+%D <dchem>
+%D <structure>
+%D <component>
+%D <graphic>SIX,B</graphic>
+%D <graphic>R135</graphic>
+%D </component>
+%D <component>
+%D <graphic>R246</graphic>
+%D </component>
+%D <component>
+%D <graphic>RZ</graphic>
+%D <text>A,B,C,D,E,F</text>
+%D </component>
+%D <component>
+%D <graphic>Z</graphic>
+%D <oxidation n="3">A</oxidation>
+%D <text>A</text>
+%D <annotation location="t">
+%D <text>B</text>
+%D <caption>x<context:b>x<context:compound token="*"/>x</context:b>x</caption>
+%D </annotation>
+%D <oxidation n="3" sign="+">B</oxidation>
+%D <text>C,D,E,F</text>
+%D </component>
+%D </structure>
+%D <structure>
+%D <component>
+%D <graphic>SIX,B</graphic>
+%D <graphic>r135</graphic>
+%D </component>
+%D <component>
+%D <graphic>R246</graphic>
+%D </component>
+%D <component>
+%D <graphic>RZ</graphic>
+%D <text>A,B,C,D,E,F</text>
+%D </component>
+%D </structure>
+%D </dchem>
+%D \stopbuffer
+%D
+%D \typebuffer
+
+% \ifx\XMLgtoks\undefined \newtoks\XMLgtoks \fi
+% \ifx\XMLttoks\undefined \newtoks\XMLttoks \fi
+%
+% \defineXMLenvironment [structure]
+% {\startchemical\ignorespaces}
+% {\relax\stopchemical}
+%
+% \def\chemicalXMLg#1% \defineXMLcollect [graphic] \XMLgtoks
+% {\doifelsenothing{\the\XMLgtoks}
+% {\doglobal\appendtoks #1\to\XMLgtoks\ignorespaces}
+% {\doglobal\appendtoks,#1\to\XMLgtoks\ignorespaces}}
+%
+% \def\chemicalXMLt#1%
+% {\doifelsenothing{\the\XMLttoks}
+% {\doglobal\appendtoks #1\to\XMLttoks\ignorespaces}
+% {\doglobal\appendtoks,#1\to\XMLttoks\ignorespaces}}
+%
+% \defineXMLenvironment [component] [type=]
+% {\global\XMLgtoks\emptytoks
+% \global\XMLttoks\emptytoks
+% \defineXMLargument[graphic]\chemicalXMLg
+% \defineXMLargument[text]\chemicalXMLt
+% \ignorespaces}
+% {\expanded{\chemical[\the\XMLgtoks][\the\XMLttoks]}%
+% \ignorespaces}
+%
+% \defineXMLargument [oxidation] [sign=,n=1] \chemicalXMLo % +/- 1..7
+%
+% \def\chemicalXMLo#1%
+% {\expanded{\chemicalXMLt
+% {\noexpand\chemicaloxidation{\XMLop{sign}}{\XMLop{n}}{#1}}}%
+% \ignorespaces}
+%
+% \defineXMLenvironment [annotation] [location=]
+% {\bgroup
+% \defineXMLenvironmentsave[text]{\ignorespaces}{\ignorespaces}%
+% \defineXMLenvironmentsave[caption]{\ignorespaces}{\ignorespaces}%
+% \ignorespaces}
+% {\scratchtoks{\chemicalright}%
+% \processaction
+% [\XMLop{location}]
+% [ t=>\scratchtoks{\chemicaltop},
+% b=>\scratchtoks{\chemicalbottom},
+% l=>\scratchtoks{\chemicalleft},
+% r=>\scratchtoks{\chemicalright},
+% lc=>\scratchtoks{\chemicalleftcentered},
+% rc=>\scratchtoks{\chemicalrightcentered},
+% tl=>\scratchtoks{\chemicaltopleft},
+% bl=>\scratchtoks{\chemicalbottomleft},
+% tr=>\scratchtoks{\chemicaltopright},
+% br=>\scratchtoks{\chemicalbottomright},
+% lt=>\scratchtoks{\chemicallefttop},
+% lb=>\scratchtoks{\chemicalleftbottom},
+% rt=>\scratchtoks{\chemicalrighttop},
+% rb=>\scratchtoks{\chemicalrightbottom},
+% x=>\scratchtoks{\chemicaltighttext},
+% sl=>\scratchtoks{\chemicalsmashedleft},
+% sm=>\scratchtoks{\chemicalsmashedmiddle},
+% sr=>\scratchtoks{\chemicalsmashedright}]%
+% \expanded{\chemicalXMLt
+% {\the\scratchtoks{\XMLflush{text}}{\XMLflush{caption}}}}%
+% \egroup
+% \ignorespaces}
+%
+% \defineXMLenvironment [forever]
+% {\chemicalXMLt{\[}\ignorespaces}
+% {\chemicalXMLt{\]}\ignorespaces}
+
+\ifx\XMLgtoks\undefined \newtoks\XMLgtoks \fi
+\ifx\XMLttoks\undefined \newtoks\XMLttoks \fi
+
+\startXMLmapping [cml]
+
+% this will be a more natural method; this also triggers it
+
+\installXMLunknownremapping
+
+% extensions
+
+\remapXMLsequence [structure] [CPA] \doCMLstructure
+\remapXMLsequence [component] [CPA] \doCMLcomponent
+\remapXMLsequence [graphic] [CPA] \doCMLgraphic
+\remapXMLsequence [text] [CPA] \doCMLtext
+
+\remapXMLsequence [caption] [CPA] \doCMLcaption
+\remapXMLsequence [oxidation] [CPA] \doCMLoxidation
+\remapXMLsequence [annotation][CPA] \doCMLannotation
+\remapXMLsequence [forever] [CPA] \doCMLforever
+
+\def\doCMLstructure#1#2%
+ {\startchemical\ignorespaces#2\unskip\stopchemical}
+
+\def\doCMLgraphic#1#2%
+ {\doifelsenothing{\the\XMLgtoks}
+ {\uppercase{\doglobal\appendtoks #2\to\XMLgtoks\ignorespaces}}
+ {\uppercase{\doglobal\appendtoks,#2\to\XMLgtoks\ignorespaces}}%
+ \ignorespaces}
+
+\def\doCMLtext#1#2%
+ {\doifelsenothing{\the\XMLttoks}
+ {\doglobal\appendtoks #2\to\XMLttoks\ignorespaces}
+ {\doglobal\appendtoks,#2\to\XMLttoks\ignorespaces}%
+ \ignorespaces}
+
+\def\doCMLcomponent#1#2%
+ {\global\XMLgtoks\emptytoks
+ \global\XMLttoks\emptytoks
+ \ignorespaces#2\unskip
+ \expanded{\chemical[\the\XMLgtoks][\the\XMLttoks]}%
+ \ignorespaces}
+
+\def\doCMLannotation#1#2%
+ {\getXMLarguments{cml}{location="" #1}%
+ \def\dodoCMLannotation##1%
+ {\doCMLtext\empty{##1%
+ {\let\doCMLtext \secondoftwoarguments\processXMLRchild{text}{#2}}%
+ {\let\doCMLcaption\unmapXMLdata \processXMLRchild{caption}{#2}}}}%
+ \processaction
+ [\XMLpar{cml}{location}{r}]
+ [ t=>\dodoCMLannotation\chemicaltop,
+ b=>\dodoCMLannotation\chemicalbottom,
+ l=>\dodoCMLannotation\chemicalleft,
+ r=>\dodoCMLannotation\chemicalright,
+ lc=>\dodoCMLannotation\chemicalleftcentered,
+ rc=>\dodoCMLannotation\chemicalrightcentered,
+ tl=>\dodoCMLannotation\chemicaltopleft,
+ bl=>\dodoCMLannotation\chemicalbottomleft,
+ tr=>\dodoCMLannotation\chemicaltopright,
+ br=>\dodoCMLannotation\chemicalbottomright,
+ lt=>\dodoCMLannotation\chemicallefttop,
+ lb=>\dodoCMLannotation\chemicalleftbottom,
+ rt=>\dodoCMLannotation\chemicalrighttop,
+ rb=>\dodoCMLannotation\chemicalrightbottom,
+ x=>\dodoCMLannotation\chemicaltighttext,
+ sl=>\dodoCMLannotation\chemicalsmashedleft,
+ sm=>\dodoCMLannotation\chemicalsmashedmiddle,
+ sr=>\dodoCMLannotation\chemicalsmashedright]%
+ \ignorespaces}
+
+\def\doCMLoxidation#1#2%
+ {\getXMLarguments{cml}{sign="" n="1" #1}%
+ \expanded{\doCMLtext{}%
+ {\noexpand\chemicaloxidation{\XMLpar{cml}{sign}{}}{\XMLpar{cml}{n}{}}{#2}}}%
+ \ignorespaces}
+
+\def\doCMLforever#1#2{\[#2\]}
+
+\stopXMLmapping
+
+\endinput
diff --git a/tex/context/modules/mkii/x-chemml.xsd b/tex/context/modules/mkii/x-chemml.xsd
new file mode 100644
index 000000000..b51121911
--- /dev/null
+++ b/tex/context/modules/mkii/x-chemml.xsd
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ <p>This schema covers (basic presentational) Chemical
+ markup. We will extend this schema with names and
+ predefined components.</p>
+ <p>author: Hans Hagen, copyright: PRAGMA-ADE / Hasselt NL</p>
+ </xsd:documentation>
+</xsd:annotation>
+
+<xsd:element type="chemType">
+ <xsd:sequence>
+ <xsd:element ref="chemicalComponentType" />
+ <xsd:choice>
+ <xsd:element ref="chemicalActionType" />
+ <xsd:element ref="chemicalBondType" />
+ </xsd:choice>
+ </xsd:sequence>
+</xsd:element>
+
+<xsd:element name="chem" type="chemType" />
+<xsd:element name="ichem" type="chemType" />
+<xsd:element name="dchem" type="chemType" />
+
+<xsd:element name="molecule">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="ion" />
+ <xsd:element name="atom" />
+ </xsd:choice>
+ <xsd:element name="caption" type="chemicalCaptionType" />
+ </xsd:sequence>
+ <xsd:attribute name="n" type="xsd:positiveInteger" />
+ </xsd:complexType>
+</xsd:element>
+
+<xsd:element name="ion">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="atom" />
+ </xsd:sequence>
+ <xsd:attribute name="n" type="xsd:positiveInteger" />
+ <xsd:attribute name="charge" type="xsd:integer" />
+ </xsd:complexType>
+</xsd:element>
+
+<xsd:element name="atom" type="xsd:string">
+ <xsd:complexType>
+ <xsd:attribute name="n" type="xsd:positiveInteger"/>
+ <xsd:attribute name="charge" type="xsd:integer" />
+ <xsd:attribute name="protons" type="xsd:positiveInteger" />
+ <xsd:attribute name="weight" type="xsd:positiveInteger" />
+ </xsd:complexType>
+</xsd:element>
+
+<xsd:complexType name="chemicalActionType">
+ <xsd:choice>
+ <xsd:element name="plus" type="chemicalCaptionType" />
+ <xsd:element name="minus" type="chemicalCaptionType" />
+ <xsd:element name="equal" type="chemicalCaptionType" />
+ <xsd:element name="gives" type="chemicalCaptionType" />
+ <xsd:element name="equilibrium" type="chemicalCaptionType" />
+ <xsd:element name="mesomeric" type="chemicalCaptionType" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="chemicalBondType">
+ <xsd:choice>
+ <xsd:element name="singlebond" />
+ <xsd:element name="doublebond" />
+ <xsd:element name="triplebond" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="chemicalComponentType">
+ <xsd:choice>
+ <xsd:element ref="molecule" />
+ <xsd:element ref="ion" />
+ <xsd:element ref="atom" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="chemicalCaptionType" minOccurs="0" maxOccurs="2">
+ <xsd:sequence>
+ <xsd:element name="caption" type="xsd:string" minOccurs="0" maxOccurs="2" />
+ </xsd:sequence>
+</xsd:complexType>
+
+</xsd:schema>
diff --git a/tex/context/modules/mkii/x-contml.mkii b/tex/context/modules/mkii/x-contml.mkii
new file mode 100644
index 000000000..22fffa50a
--- /dev/null
+++ b/tex/context/modules/mkii/x-contml.mkii
@@ -0,0 +1,491 @@
+%M \usemodule [contml] \autoXMLnamespace [context]
+%M \definefilesynonym [context] [x-contml.xsd]
+
+%D \module
+%D [ file=x-contml,
+%D version=mid 2001,
+%D title=\CONTEXT\ XML Support,
+%D subtitle=Basic \CONTEXT\ commands,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% This module provides some basic \XML\ elements. These definitions
+% are highly experimental and serve as a playground for interface
+% development.
+
+\unprotect
+
+%D \elements {include}
+%D
+%D \startbuffer
+%D You can include another file in the current document with the
+%D <element>include</element> element. When including the file, &context;
+%D will look at the suffix, in order to decide how to include the file.
+%D
+%D <verbatim>
+%D <line><include name="mine"/></line>
+%D <line><include name="mine" type="txt"/></line>
+%D <line><include name="mine" type="tex"/></line>
+%D </verbatim>
+%D \stopbuffer
+%D
+%D \showelements [context] [include]
+
+\defineXMLsingular [context:include] [name=,type=xml]
+ {\doifsomethingXMLop{name}
+ {\processaction
+ [\XMLop{type}]
+ [xml=>\readfile{\XMLop{name}}\donothing\donothing,
+ tex=>{{\disableXML\readfile{\XMLop{name}}\donothing\donothing}},
+ txt=>{{\disableXML\typefile{\XMLop{name}}}}]}}
+
+% or, nicer:
+%
+% \defineXMLsingular [context:include] [name=unknown,type=txt]
+% {\XMLval{include:type}{\XMLop{type}}{}}
+%
+% \mapXMLvalue {include:type} {xml} {\readfile{\XMLop{name}}\donothing\donothing}
+% \mapXMLvalue {include:type} {tex} {{\disableXML\readfile{\XMLop{name}}\donothing\donothing}}
+% \mapXMLvalue {include:type} {txt} {{\disableXML\typefile{\XMLop{name}}}}
+
+%D \elements {compound}
+%D
+%D \startbuffer
+%D Instead of using hard coded compound tokens, you should use the
+%D <element>compound</element> element, as in high<compound token="/" />low.
+%D The overhead in keying is rewarded with proper symbols and hyphenation.
+%D \stopbuffer
+%D
+%D \showelements [context] [compound]
+
+\ifx\normalcompound\undefined \let\normalcompound=| \fi
+
+% \defineXMLsingular [context:compound] [token=]
+% {\expanded{\normalcompound\XMLop{token}}|}
+
+% \defineXMLsingular [context:compound] [token=]
+% {\ifmmode
+% \doifXMLop{token}{\XMLop{token}}{\compoundhyphen}%
+% \else
+% \expanded{\normalcompound\XMLop{token}}|%
+% \fi}
+
+\defineXMLsingular [context:compound] [token=]
+ {\mathortext % disc comm looks ahead, so \relax
+ {\doifXMLop{token}{\XMLop{token}}\compoundhyphen}%
+ {\expanded{\directdiscretionary{\XMLop{token}}}\relax}}
+
+\defineXMLenvironmentsave [context:cp]
+ {}
+ {\expanded{\directdiscretionary{\XMLflush{cp}}}\relax}
+
+%D \elements {p}
+%D
+%D \startbuffer
+%D <p>Although for &tex; it is often enough to mark the end of a paragraph,
+%D in &xml; we want to add a bit more structure. <p/> This permits a more
+%D robust implementation of begin<compound/>of<compound/>par actions</p>
+%D \stopbuffer
+%D
+%D \showelements [context] [p]
+
+\defineXMLenvironment [context:p] {} \endgraf
+\defineXMLsingular [context:p] \endgraf
+
+%D \elements {pageref,textref,lineref}
+%D
+%D \startbuffer
+%D You can ask for a page (<pageref label="lastpage">the last pagenumber
+%D is</pageref> aka page <pageref label="lastpage"/>), text or line reference
+%D with the following three elements. The label may be any valid &context;
+%D reference label.
+%D \stopbuffer
+%D
+%D \showelements [context] [references]
+
+\defineXMLpickup [context:pageref] [label=] {\at} {[\XMLop{label}]}
+\defineXMLpickup [context:textref] [label=] {\in} {[\XMLop{label}]}
+\defineXMLpickup [context:lineref] [label=] {\inline} {[\XMLop{label}]}
+
+%D \elements{text}
+%D
+%D \startbuffer
+%D If you have a self contained &xml; file, you need to signal &context; the
+%D begin and end of the document. The following elements can be used for
+%D that purpose:
+%D
+%D <verbatim>
+%D <line><text></line>
+%D <line> ...</line>
+%D <line></text></line>
+%D </verbatim>
+%D \stopbuffer
+%D
+%D \showelements [context] [text]
+
+\defineXMLenvironment [context:text] \starttext \stoptext
+
+%D \elements {em}
+%D
+%D \startbuffer
+%D Authors often want some control over the way a text is typeset, which is
+%D why we provide the <element>em</element> element. We may only hope that
+%D the author is <em>consistent</em> in his decisions on what to emphasize.
+%D \stopbuffer
+%D
+%D \showelements [context] [em]
+
+\defineXMLgrouped [context:em] \em
+
+%D \elements {b}
+%D
+%D \startbuffer
+%D Bold is not always <b>beautiful</b> but if you really want it, you can
+%D get it by using this element.
+%D \stopbuffer
+%D
+%D \showelements [context] [b]
+
+\defineXMLgrouped [context:b] \bf
+
+%D \elements {verbatim,typing,line,verb,type}
+%D
+%D \startbuffer
+%D Although the following method can be used to typeset a piece of code
+%D verbatim
+%D
+%D <![CDATA[
+%D Dit \is nogal verbatim !
+%D Dit is {nogal} verbatim !
+%D Dit is <nogal> verbatim !
+%D ]]>
+%D
+%D we prefer the more structured:
+%D
+%D <verbatim>
+%D <line>Dit \is nogal verbatim !</line>
+%D <line>Dit is {nogal} verbatim !</line>
+%D <line>Dit is <nogal> verbatim !</line>
+%D </verbatim>
+%D \stopbuffer
+%D
+%D The element to tag in<compound/>line verbatim is <type><verb></type>.
+%D
+%D \showelements [context] [verbatim]
+
+\defineXMLenvironment [context:verbatim]
+ {\startpacked
+ \defineXMLargument[context:line]{\endgraf\type}}
+ {\stoppacked}
+
+\defineXMLenvironment [context:typing]
+ {\startpacked\defineXMLargument[context:line]{\endgraf\type}}
+ {\stoppacked}
+
+\defineXMLargument [context:verb] \type
+\defineXMLargument [context:type] \type
+
+%D \elements {itemize,item}
+%D
+%D \startbuffer
+%D Itemized lists are quite common in documents, al least in the ones that
+%D we produce. For the moment we only provide a few options, later we will
+%D hook it into the &context; attribute handler.
+%D
+%D <itemize type="a">
+%D <item label="bla"> test </item>
+%D <item> test </item>
+%D </itemize>
+%D
+%D <itemize packed="yes">
+%D <item label="more bla"> test </item>
+%D <item> test <em>what?</em></item>
+%D </itemize>
+%D \stopbuffer
+%D
+%D \showelements [context] [itemize]
+
+\defineXMLenvironment [context:itemize] [type=,packed=]
+ {\let\XMLoptions\empty
+ \doifsomethingXMLop{type}{\addtocommalist{\XMLop{type}}\XMLoptions}%
+ \doifXMLop{packed}{yes}{\addtocommalist{packed}\XMLoptions}%
+ \expanded{\startitemize[\XMLoptions]}}
+ {\stopitemize}
+
+\defineXMLenvironment [context:item] [label=]
+ {\expanded{\item[\XMLop{label}]}}
+ {\endgraf}
+
+%D \elements {externalfigure}
+%D
+%D \startbuffer
+%D The previous examples already demonstrated how we can include a graphic:
+%D
+%D <verbatim>
+%D <line><externalfigure file="cow" width="5cm" /></line>
+%D </verbatim>
+%D \stopbuffer
+%D
+%D \showelements [context] [externalfigure]
+
+\defineXMLsingular [context:externalfigure] [\??ef] [base=,label=,file=]
+ {\bgroup % \getXMLta \expandXMLta \expandXMLtp{file}%
+ \expandXMLta
+ \getXMLta % expand entities first
+ \doifelsenothing{\XMLtp{label}}
+ {\expanded{\externalfigure[\XMLtp{file}][\XMLta]}}
+ {\doifsomething{\XMLtp{base}}{\usefigurebase[\XMLtp{base}]}%
+ \expanded{\externalfigure[\XMLtp{label}][\XMLta]}}
+ \egroup}
+
+%D \elements {fixed}
+%D \setupexternalfigures[directory={../sample}]
+%D \startbuffer
+%D Something fixed will end up at the place where it defined in the input
+%D stream. The main idea behind this element is that it gives you control
+%D over the placement.
+%D
+%D <itemize>
+%D <item>
+%D <fixed align="high">
+%D <content>
+%D <externalfigure file="cow" frame="on" height="1cm" />
+%D </content>
+%D </fixed>
+%D </item>
+%D </itemize>
+%D \stopbuffer
+%D
+%D \showelements [context] [fixed]
+
+\defineXMLenvironment [context:fixed] [type=figure,location=,label=]
+ {\bgroup
+ \defineXMLsave[context:caption]
+ \defineXMLsave[context:content]}
+ {\expanded{\startfixed[\XMLop{location}]}%
+ \doifXMLdataelse{context:caption}
+ {\startcombination[1*1]
+ {\XMLflush{context:content}} {\XMLflush{context:caption}}
+ \stopcombination}
+ {\XMLflush{context:content}}%
+ \stopfixed
+ \egroup}
+
+%D \elements {float}
+%D \setupexternalfigures[directory={../sample}]
+%D \startbuffer
+%D A floating body will be placed at the first location available, unless
+%D a location is specified. As with the <element>fixed</element> element,
+%D you can provide a caption.
+%D
+%D <float type="figure">
+%D <content>
+%D <externalfigure file="cow" frame="on" height="3cm" />
+%D </content>
+%D <caption>This is a cow!</caption>
+%D </float>
+%D \stopbuffer
+%D
+%D \showelements [context] [float]
+
+\defineXMLenvironment [context:float] [type=figure,location=here,label=]
+ {\bgroup
+ \defineXMLsave[context:caption]
+ \defineXMLsave[context:content]}
+ {\expanded
+ {\placefloat
+ [\XMLop{type}] [\XMLop{location}] [\XMLop{label}]
+ {\XMLflush{context:caption}} {\XMLflush{context:content}}}
+ \egroup}
+
+%D \elements {quotation,quote}
+%D
+%D \startbuffer
+%D There is a (not so) subtle difference between a display
+%D <quotation>quotation</quotation> and an <quote>in<compound/>line</quote>
+%D one.
+%D \stopbuffer
+%D
+%D \showelements [context] [table]
+
+\defineXMLgrouped [context:quote] \quote
+\defineXMLgrouped [context:quotation] \quotation
+
+%D \elements {table,tr,td}
+%D
+%D \startbuffer
+%D There are (currently) three table mechanisms in &context;. One of them
+%D resembles the well known &html; tables.
+%D
+%D <?context-command \startlinecorrection[blank] ?>
+%D <table>
+%D <tr> <td>one</td> <td>a</td> <td>first </td> </tr>
+%D <tr> <td>two</td> <td>b</td> <td>second</td> </tr>
+%D </table>
+%D <?context-command \stoplinecorrection ?>
+%D
+%D As you can see here, we use a similar syntax but stick to the &context;
+%D attributes (which provide quite advanced control over the layout).
+%D
+%D <?context-command \startlinecorrection[blank] ?>
+%D <table frame="off" background="color" color="white">
+%D <tr backgroundcolor="red"> <td>xx</td> <td>xx</td> </tr>
+%D <tr backgroundcolor="green"> <td>xx</td> <td>xx</td> </tr>
+%D </table>
+%D <?context-command \stoplinecorrection ?>
+%D \stopbuffer
+%D
+%D \showelements [context] [table]
+
+\defineXMLenvironment [context:table] [\@@tbl\@@tbl]
+ {\bgroup
+ \defineXMLnested [context:tr] [\@@tbl] {\expanded{\bTR[\theXMLarguments{\@@tbl}}]} \eTR
+ \defineXMLnested [context:td] [\@@tbl] {\expanded{\bTD[\theXMLarguments{\@@tbl}}]} \eTD
+ \expanded{\bTABLE[\theXMLarguments{\@@tbl\@@tbl}]}}
+ {\eTABLE
+ \egroup}
+
+%D \elements {tabulate,tspec,thead,tbody,ttail,trule,tr,td}
+%D
+%D \startbuffer
+%D The second mechanism that we support is tabulation. The advantage of this
+%D mechanism is that it it well tuned for tables that have much text in the
+%D cells and cross page boundaires.
+%D
+%D <tabulate>
+%D <tspec>
+%D <tcell align="left"/> <tcell align="middle"/> <tcell align="right"/>
+%D </tspec>
+%D <thead>
+%D <trule/>
+%D <tr> <td> bagger </td> <td> bagger </td> <td> bagger </td> </tr>
+%D <trule/>
+%D </thead>
+%D <ttail>
+%D <trule/>
+%D </ttail>
+%D <tbody>
+%D <tr> <td> bagger </td> <td> bagger </td> <td> bagger </td> </tr>
+%D <tr> <td> bagg </td> <td> ger </td> <td> gr </td> </tr>
+%D <tr> <td> bag </td> <td> er </td> <td> gger </td> </tr>
+%D </tbody>
+%D </tabulate>
+%D \stopbuffer
+%D
+%D \showelements [context] [tabulate]
+
+\newtoks\XMLtabtoks
+
+\defineXMLgrouped [context:tabulate] {\XMLtabtoks{|l|p|}}
+
+\defineXMLpickup [context:tbody]
+ {\expanded{\definetabulate[dummy][\the\XMLtabtoks]}
+ \startdummy\XMLflush{context:thead}}
+ {\XMLflush{context:ttail}\stopdummy}
+
+\defineXMLsave [context:thead]
+\defineXMLsave [context:ttail]
+
+\defineXMLenvironment[context:tspec]
+ {\XMLtabtoks\emptytoks}
+ {\appendtoks|\to\XMLtabtoks}
+
+\defineXMLsingular [context:trule] % verrrry ugly
+ {\crcr\noalign{\kern-\lineheight}\HL}
+
+\defineXMLsingular [context:tcell] [align=]
+ {\appendtoks|\to\XMLtabtoks
+ \expanded{\processallactionsinset
+ [\XMLop{align}]}
+ [ paragraph=>\appendtoks p\to\XMLtabtoks,
+ left=>\appendtoks l\to\XMLtabtoks,
+ right=>\appendtoks r\to\XMLtabtoks,
+ center=>\appendtoks c\to\XMLtabtoks,
+ middle=>\appendtoks c\to\XMLtabtoks]}
+
+\defineXMLenvironment [context:tr] {\ignorespaces} {\NC\NR}
+\defineXMLenvironment [context:td] {\NC} {\ignorespaces}
+
+%D \elements {hide}
+%D
+%D \startbuffer
+%D This is the way to [<hide>this is gone</hide>] something for the
+%D typesetting engine. Normally this element is only used for testing
+%D purposes.
+%D \stopbuffer
+%D
+%D \showelements [context] [tabulate]
+
+\defineXMLignore[context:hide]
+
+%D \elements {unknown}
+%D
+%D \startbuffer
+%D We can go on and on and <unknown/> with defining elements that map onto
+%D &context; commands, but why not just use &tex; input syntax then?
+%D \stopbuffer
+%D
+%D \showelements [context] [unknown]
+
+\defineXMLsingular [context:unknown] \unknown
+
+%D A (for the moment) private one.
+
+\defineXMLargument [context:element] \type
+
+%D The following common schema definitions apply:
+%D
+%D {\setupcolors[state=stop]\showXSDcomponent[context][definitions]}
+
+\defineXMLargument [context:chapter] [label=] {\chapter[\XMLop{label}]}
+\defineXMLargument [context:section] [label=] {\section[\XMLop{label}]}
+\defineXMLargument [context:subsection] [label=] {\subsection[\XMLop{label}]}
+\defineXMLargument [context:subsubsection] [label=] {\subsubsection[\XMLop{label}]}
+\defineXMLargument [context:subsubsubsection] [label=] {\subsubsubsection[\XMLop{label}]}
+
+\defineXMLargument [context:title] [label=] {\title[\XMLop{label}]}
+\defineXMLargument [context:subject] [label=] {\subject[\XMLop{label}]}
+\defineXMLargument [context:subsubject] [label=] {\subsubject[\XMLop{label}]}
+\defineXMLargument [context:subsubsubject] [label=] {\subsubsubject[\XMLop{label}]}
+\defineXMLargument [context:subsubsubsubject] [label=] {\subsubsubsubject[\XMLop{label}]}
+
+\defineXMLenvironment [context:frontmatter] \startfrontmatter \stopfrontmatter
+\defineXMLenvironment [context:bodymatter] \startbodymatter \stopbodymatter
+\defineXMLenvironment [context:backmatter] \startbackmatter \stopbackmatter
+\defineXMLenvironment [context:appendices] \startappendices \stopappendices
+
+\defineXMLargument [context:index] [key=]
+ {\doifelsenothingXMLop{key}{\index}{\expanded{\index[\XMLop{key}]}}}
+
+% \enableXMLfiledata
+
+% Needed for example (stickers and so):
+
+\defineXMLenvironment [context:makeup]
+ \startstandardmakeup \stopstandardmakeup
+
+\protect \endinput
+
+% TO DO
+
+\defineXMLenvironment [combination] [columns=2,rows=1]
+ {\scratchtoks\emptytoks
+ \expanded{\appendtoks \noexpand \startcombination
+ [\XMLop{columns}*\XMLop{rows}]}\to \scratchtoks}
+ {\appendtoks \stopcombination \to \scratchtoks
+ \the\scratchtoks}
+
+\defineXMLprocess[combinationentry]
+
+\defineXMLpickup [combinationitem]
+ {\appendtoks\bgroup}{\egroup\to\scratchtoks}
+
+\defineXMLpickup [combinationcaption]
+ {\appendtoks\bgroup}{\egroup\to\scratchtoks}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-contml.xsd b/tex/context/modules/mkii/x-contml.xsd
new file mode 100644
index 000000000..3b71e31e8
--- /dev/null
+++ b/tex/context/modules/mkii/x-contml.xsd
@@ -0,0 +1,375 @@
+<?xml version="1.0"?>
+
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+
+<xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ This schema describes a class of presentations. The structure is
+ (normally) reflected in the design.
+
+ author: Hans Hagen, copyright: PRAGMA-ADE / Hasselt NL
+ </xsd:documentation>
+</xsd:annotation>
+
+
+<?context-block begin definitions ?>
+
+ <xsd:complexType name="filename.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value='[a-zA-Z0-9\-\:\.]*' />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="filetype.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="tex" />
+ <xsd:enumeration value="xml" />
+ <xsd:enumeration value="txt" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="confirmation.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="yes" />
+ <xsd:enumeration value="no" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="conversion.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value='(a|A|n|g|G|r|R|1|2|3|4)' />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="reference.label.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value='([a-zA-Z0-9\-\:]*' />
+ </xsd:restriction>
+ </xsd:complexType>
+
+<?context-block end definitions ?>
+
+
+<?context-block begin text ?>
+
+ <xsd:element name="presentation" mixed="true" />
+
+<?context-block end text ?>
+
+
+<?context-block begin p ?>
+
+ <xsd:element name="p" mixed="true" />
+
+<?context-block end p ?>
+
+
+<?context-block begin hide ?>
+
+ <xsd:element name="hide" mixed="true" />
+
+<?context-block end hide ?>
+
+
+<?context-block begin em ?>
+
+ <xsd:element name="em" mixed="true" />
+
+<?context-block end em ?>
+
+
+<?context-block begin b ?>
+
+ <xsd:element name="b" mixed="true" />
+
+<?context-block end b ?>
+
+
+<?context-block begin quote ?>
+
+ <xsd:element name="quote" mixed="true" />
+ <xsd:element name="quotation" mixed="true" />
+
+<?context-block end quote ?>
+
+
+<?context-block begin include ?>
+
+ <xsd:attributeGroup name="include.attributes">
+ <xsd:attribute name="file" type="filename.value" use="required" />
+ <xsd:attribute name="type" type="filetype.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType type="include.type">
+ <xsd:attributeGroup ref="include.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="include" type="include.type" />
+
+<?context-block end include ?>
+
+
+<?context-block begin compound ?>
+
+ <xsd:attributeGroup name="compound.attributes">
+ <xsd:attribute name="token" type="xsd:string" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType type="compound.type">
+ <xsd:attributeGroup ref="compound.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="compound" type="compound.type" />
+
+<?context-block end compound ?>
+
+
+<?context-block begin references ?>
+
+ <xsd:attributeGroup name="reference.attributes">
+ <xsd:attribute name="label" type="reference.label.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType type="reference.type">
+ <xsd:attributeGroup ref="reference.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="lineref" type="reference.type" />
+ <xsd:element name="pageref" type="reference.type" />
+ <xsd:element name="textref" type="reference.type" />
+
+<?context-block end references ?>
+
+
+<?context-block begin unknown ?>
+
+ <xsd:element name="unknown"/>
+
+<?context-block end unknown ?>
+
+
+<?context-block begin verbatim ?> <!-- string or anyType -->
+
+ <xsd:complexType name="verbatim.verbatim">
+ <xsd:sequence maxOccurs="unbounded" >
+ <xsd:element name="line" type="xsd:string" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="verbatim" type="verbatim.verbatim" />
+ <xsd:element name="typing" type="verbatim.verbatim" />
+
+ <xsd:element name="verb" type="xsd:string" />
+ <xsd:element name="type" type="xsd:string" />
+
+<?context-block end verbatim ?>
+
+
+<?context-block begin itemize ?>
+
+ <xsd:attributeGroup name="itemize.attributes">
+ <xsd:attribute name="type" type="conversion.value" />
+ <xsd:attribute name="packed" type="confirmation.value" />
+ <xsd:attribute name="label" type="reference.label.value" />
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="item.attributes">
+ <xsd:attribute name="label" type="reference.label.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="item.type" mixed="true">
+ <xsd:attributeGroup ref="item.attributes" />
+ </xsd:complexType>
+
+ <xsd:complexType name="itemize.type">
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <xml:element name="item" type="item.type" />
+ </xsd:sequence>
+ <xsd:attributeGroup ref="itemize.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="itemize" type="itemize.type" />
+
+<?context-block end itemize ?>
+
+
+<?context-block begin fixed ?>
+
+ <xsd:complexType name="fixed.type.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="figure" />
+ <xsd:enumeration value="table" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="fixed.location.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="high" />
+ <xsd:enumeration value="low" />
+ <xsd:enumeration value="lohi" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="fixed.attributes">
+ <xsd:attribute name="type" type="fixed.type.value" />
+ <xsd:attribute name="location" type="fixed.location.value" />
+ <xsd:attribute name="label" type="reference.label.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="fixed.type">
+ <xsd:all>
+ <xsd:element name="caption" mixed="true" />
+ <xsd:element name="content" mixed="true" />
+ </xsd:all>
+ <xsd:attributeGroup ref="fixed.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="fixed" type="fixed.type" />
+
+<?context-block end fixed ?>
+
+
+<?context-block begin float ?>
+
+ <xsd:complexType name="float.type.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="figure" />
+ <xsd:enumeration value="table" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:complexType name="float.location.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="high" />
+ <xsd:enumeration value="low" />
+ <xsd:enumeration value="lohi" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="float.attributes">
+ <xsd:attribute name="type" type="float.type.value" />
+ <xsd:attribute name="location" type="float.location.value" />
+ <xsd:attribute name="label" type="reference.label.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="float.type">
+ <xsd:all>
+ <xsd:element name="caption" mixed="true" />
+ <xsd:element name="content" mixed="true" />
+ </xsd:all>
+ <xsd:attributeGroup ref="float.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="float" type="float.type" />
+
+<?context-block end float ?>
+
+
+<?context-block begin externalfigure ?>
+
+ <xsd:attributeGroup name="externalfigure.attributes">
+ <xsd:extension base="context.kernel.externalfigure.attributes">
+ <xsd:attribute name="base" type="filename.value"/>
+ <xsd:attribute name="file" type="filename.value"/>
+ <xsd:attribute name="label" type="reference.label.value"/>
+ </xsd:extension>
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="externalfigure.type">
+ <xsd:attributeGroup ref="externalfigure.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="externalfigure" type="externalfigure.type" />
+
+<?context-block end externalfigure ?>
+
+
+<?context-block begin table ?>
+
+ <xsd:attributeGroup name="table.attributes">
+ <!-- these elements inherit ConTeXt TABLE parameters -->
+ <xsd:extension base="context.kernel.table.attributes" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="table.td.type" mixed="true">
+ <xsd:attributeGroup name="table.attributes" />
+ </xsd:complexType>
+
+ <xsd:complexType name="table.tr.type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="td" type="table.td.type" />
+ </xsd:sequence>
+ <xsd:attributeGroup name="table.attributes" />
+ </xsd:complexType>
+
+ <xsd:complexType name="table.type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="tr" type="table.tr.type" />
+ </xsd:sequence>
+ <xsd:attributeGroup name="table.attributes" />
+ </xsd:complexType>
+
+ <xsd:element name="table" type="table.type" />
+
+<?context-block end table ?>
+
+
+<?context-block begin tabulate ?>
+
+ <xsd:complexType name="tabulate.td.type" mixed="true">
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.tr.type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="td" type="tabulate.td.type" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.base.type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="tr" type="tabulate.tr.type" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.align.value">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="high" />
+ <xsd:enumeration value="low" />
+ <xsd:enumeration value="lohi" />
+ </xsd:restriction>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="tabulate.tcell.attributes">
+ <xsd:attribute name="align" type="tabulate.align.value" />
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="tabulate.tcell.type" mixed="true">
+ <xsd:attributeGroup ref="tabulate.tcell.attributes" />
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.tcell.type">
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.tcells.type">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="tcell" type="tabulate.tcell.type" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="tabulate.type">
+ <xsd:sequence>
+ <xsd:element name="tcells" type="tabulate.tcells.type" />
+ <xsd:element name="thead" type="tabulate.base.type" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="ttail" type="tabulate.base.type" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="tbody" type="tabulate.base.type" minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="tabulate" type="tabulate.type" />
+
+<?context-block end tabulate ?>
+
+
+</xsd:schema>
diff --git a/tex/context/modules/mkii/x-corres.mkii b/tex/context/modules/mkii/x-corres.mkii
new file mode 100644
index 000000000..effd79a5b
--- /dev/null
+++ b/tex/context/modules/mkii/x-corres.mkii
@@ -0,0 +1,136 @@
+%D \module
+%D [ file=x-corres,
+%D version=2003.12.15, % replaces keep-02a cum suis
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Handling Correspondence Base,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The selection spec:
+
+\setvariables
+ [contacts]
+ [selection=,
+ file=x-corres.xml] % fall back
+
+%D First we define the group expansion pass:
+
+\startsetups[contacts:collect]
+
+ \defineXMLprocess [contacts]
+
+ \defineXMLignore [contact]
+
+ \defineXMLargument [contactfile]
+ \processfile
+
+ \defineXMLenvironmentsave [contactgroup] [label=]
+ {\startXMLmappinggroup[contacts]}
+ {\XMLaddcontactgrouptoselection
+ \stopXMLmappinggroup}
+
+\stopsetups
+
+%D Next we define the main processing pass:
+
+\startsetups[contacts:process]
+
+ \defineXMLprocess[contacts]
+
+ \defineXMLignore [contactgroup]
+
+ \defineXMLargument [contactfile]
+ \processfile
+
+ \defineXMLenvironmentsave[contact] [label=]
+ {\startXMLmappinggroup[contacts]}
+ {\XMLselectcontact
+ \stopXMLmappinggroup}
+
+\stopsetups
+
+\startXMLmapping[contacts]
+
+ \defineXMLsave [initials]
+ \defineXMLsave [formalname]
+ \defineXMLsave [informalname]
+ \defineXMLsave [title]
+ \defineXMLsave [prefix]
+ \defineXMLsave [suffix]
+ \defineXMLsave [telephone]
+ \defineXMLsave [mobiletelephone]
+ \defineXMLsave [telefax]
+ \defineXMLsave [email]
+ \defineXMLsave [address]
+ \defineXMLsave [information]
+
+ \defineXMLenvironment [p] \endgraf \endgraf
+
+ \defineXMLargument [member] \XMLaddcontacttoselection
+
+\stopXMLmapping
+
+%D The selection macros: we expand groups and replace them
+%D by contact labels in the selection spec.
+
+\def\XMLaddcontactgrouptoselection
+ {\edef\XMLcontactlist{\getvariable{contacts}{selection}}%
+ \edef\XMLgrouplabel {\XMLop{label}}%
+ \expanded{\doifinset{\XMLgrouplabel}{\XMLcontactlist}}
+ {\let\XMLgrouplist\empty
+ \XMLflush{contactgroup}%
+ \substituteincommalist\XMLgrouplabel\XMLgrouplist\XMLcontactlist
+ \expanded
+ {\globalsetvariables
+ [contacts]
+ [selection={\XMLcontactlist}]}}}
+
+\def\XMLaddcontacttoselection#1%
+ {\addtocommalist{#1}\XMLgrouplist}
+
+%D The main selector:
+
+\def\XMLselectcontact
+ {\edef\XMLcontactlist {\getvariable{contacts}{selection}}%
+ \edef\XMLcontactlabel{\XMLop{label}}%
+ \doifelsenothing{\XMLcontactlist}
+ {\donetrue}
+ {\expanded{\doifinsetelse{\XMLcontactlabel}{\XMLcontactlist}}
+ {\donetrue}
+ {\donefalse}}%
+ \ifdone
+ \XMLflush{contact}%
+ \setups[contact:handle]%
+ \fi}
+
+%D The default:
+
+\startsetups[contact:handle]
+
+ \XMLflush{address}
+
+\stopsetups
+
+\setups[contacts:process]
+
+%D Handy:
+
+\def\XMLprocesscontacts
+ {\dosingleempty\XMLprocesscontacts}
+
+\def\XMLprocesscontacts[#1]%
+ {\bgroup
+ \doifelsenothing{#1}
+ {\XMLprocesscontacts[\getvariable{contacts}{file}]}
+ {\setups[contacts:collect]%
+ \processcommacommand[#1]\processXMLfile
+ \setups[contacts:process]%
+ \processcommacommand[#1]\processXMLfile}%
+ \egroup}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-corres.rng b/tex/context/modules/mkii/x-corres.rng
new file mode 100644
index 000000000..09de5d267
--- /dev/null
+++ b/tex/context/modules/mkii/x-corres.rng
@@ -0,0 +1,170 @@
+<?xml version="1.0" ?>
+
+<?context-block begin grammar ?>
+
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+ <?context-block end grammar ?>
+
+ <?context-block begin contacts ?>
+
+ <start>
+ <ref name="contacts"/>
+ </start>
+
+ <define name="contacts">
+ <element name="contacts">
+ <zeroOrMore>
+ <choice>
+ <ref name="contacts.contact"/>
+ <ref name="contacts.contactgroup"/>
+ <ref name="contacts.contactfile"/>
+ </choice>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <?context-block end contacts ?>
+
+ <?context-block begin contact ?>
+
+ <define name="contacts.contact">
+ <element name="contact">
+ <interleave>
+ <optional> <ref name="contact.initials"/> </optional>
+ <optional> <ref name="contact.formalname"/> </optional>
+ <optional> <ref name="contact.informalname"/> </optional>
+ <optional> <ref name="contact.title"/> </optional>
+ <optional> <ref name="contact.prefix"/> </optional>
+ <optional> <ref name="contact.suffix"/> </optional>
+ <optional> <ref name="contact.telephone"/> </optional>
+ <optional> <ref name="contact.mobiletelephone"/> </optional>
+ <optional> <ref name="contact.telefax"/> </optional>
+ <optional> <ref name="contact.email"/> </optional>
+ <optional> <ref name="contact.address"/> </optional>
+ <optional> <ref name="contact.information"/> </optional>
+ </interleave>
+ <attribute name="label"/>
+ </element>
+ </define>
+
+ <?context-block end contact ?>
+
+ <?context-block begin fields ?>
+
+ <define name="contact.initials">
+ <element name="initials">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.formalname">
+ <element name="formalname">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.informalname">
+ <element name="informalname">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.title">
+ <element name="title">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.prefix">
+ <element name="prefix">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.suffix">
+ <element name="suffix">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.telephone">
+ <element name="telephone">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.mobiletelephone">
+ <element name="mobiletelephone">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.telefax">
+ <element name="telefax">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.email">
+ <element name="email">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.address">
+ <element name="address">
+ <zeroOrMore>
+ <ref name="contact.address.p"/>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="contact.information">
+ <element name="information">
+ <text/>
+ </element>
+ </define>
+
+ <define name="contact.address.p">
+ <element name="p">
+ <text/>
+ </element>
+ </define>
+
+ <?context-block end fields ?>
+
+ <?context-block begin contactgroup ?>
+
+ <define name="contacts.contactgroup">
+ <element name="contactgroup">
+ <zeroOrMore>
+ <ref name="contactgroup.member"/>
+ </zeroOrMore>
+ <attribute name="label"/>
+ </element>
+ </define>
+
+ <define name="contactgroup.member">
+ <element name="member">
+ <text/>
+ </element>
+ </define>
+
+ <?context-block end contactgroup ?>
+
+ <?context-block begin contactfile ?>
+
+ <define name="contacts.contactfile">
+ <element name="contactfile">
+ <text/>
+ </element>
+ </define>
+
+ <?context-block end contactfile ?>
+
+ <?context-block begin grammar ?>
+
+</grammar>
+
+<?context-block end grammar ?> \ No newline at end of file
diff --git a/tex/context/modules/mkii/x-dir-01.mkii b/tex/context/modules/mkii/x-dir-01.mkii
new file mode 100644
index 000000000..6e4192a13
--- /dev/null
+++ b/tex/context/modules/mkii/x-dir-01.mkii
@@ -0,0 +1,145 @@
+%D \module
+%D [ file=x-dir-01,
+%D version=2003.05.10, % around that time -)
+%D title=\CONTEXT\ Directory Handling,
+%D subtitle=Overview (1),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=12pt,
+ topspace=12pt,
+ bottomspace=32pt,
+ header=0pt,
+ footer=0pt,
+ bottomdistance=9pt,
+ bottom=18pt]
+
+\setupinteractionmenu
+ [bottom]
+ [state=start,
+ frame=off,
+ rightoffset=-3pt,
+ background=color,
+ backgroundcolor=TextColor,
+ middle=\hskip4pt,
+ left=\hfill]
+
+\startinteractionmenu[bottom]
+ \but [PreviousJump] Previous Jump \\
+ \but [previouspage] Previous Page \\
+ \but [nextpage] Next Page \\
+\stopinteractionmenu
+
+\setupbackgrounds
+ [page]
+ [backgroundoffset=3pt,
+ background=color,
+ backgroundcolor=PageColor]
+
+\setupbackgrounds
+ [text]
+ [background=color,
+ backgroundcolor=TextColor]
+
+\definecolor [PageColor] [r=.6,g=.7,b=.8]
+\definecolor [TextColor] [r=.7,g=.8,b=.9]
+\definecolor [DoneColor] [s=.5]
+
+\startmode[colorscheme-red]
+
+ \definecolor [PageColor] [r=.9,g=.7,b=.6]
+ \definecolor [TextColor] [r=.9,g=.8,b=.7]
+
+\stopmode
+
+\startmode[colorscheme-green]
+
+ \definecolor [PageColor] [r=.6,g=.8,b=.7]
+ \definecolor [TextColor] [r=.7,g=.9,b=.8]
+
+\stopmode
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [state=start,
+ menu=on,
+ color=,
+ display=new,
+ contrastcolor=DoneColor,
+ style=]
+
+\definehead
+ [directory]
+ [subject]
+
+\setuphead
+ [directory]
+ [style=\tfc]
+
+\setupbodyfont
+ [tt]
+
+\defineXMLenvironment [files] [url=]
+ {\doifelsenothing{\XMLop{url}}
+ {\xdef\XMLDIRurl{}}
+ {\xdef\XMLDIRurl{\XMLop{url}/}}
+ \startXMLignore}
+ {\stopXMLignore}
+
+\newcounter\NOfEntries
+
+\startsetups[xmldir:file]
+
+ \doglobal\increment\NOfEntries
+
+ \goto {\hbox to \hsize \bgroup
+
+ \XMLflush{base}
+ \hss
+ \hbox to 2em{\XMLflush{type}\hss}
+ \quad
+ \quad
+ \hbox to 5em{\hss\XMLflush{size}}
+ \quad
+ \quad
+ \XMLflush{date}
+
+ \egroup} [url(\XMLDIRurl\XMLop{name})]% [program(\XMLDIRurl\XMLop{name})]
+
+\stopsetups
+
+\defineXMLenvironment [directory] [name=]
+ {\directory{Path \XMLop{name}}}
+ {}
+
+\defineXMLenvironment [file] [name=]
+ {\bgroup}
+ {\setups[xmldir:file]
+ \endgraf
+ \egroup}
+
+\defineXMLsave[base]
+\defineXMLsave[type]
+\defineXMLsave[size]
+\defineXMLsave[date]
+
+\starttext
+
+ \processXMLfilegrouped{\inputfilename}
+
+ \ifnum\NOfEntries=0 There are no files found that match the pattern. \fi
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-dir-02.mkii b/tex/context/modules/mkii/x-dir-02.mkii
new file mode 100644
index 000000000..90c32d704
--- /dev/null
+++ b/tex/context/modules/mkii/x-dir-02.mkii
@@ -0,0 +1,130 @@
+%D \module
+%D [ file=x-dir-02,
+%D version=2003.05.10, % around that time -)
+%D title=\CONTEXT\ Directory Handling,
+%D subtitle=Overview (2),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=.5cm,
+ topspace=.5cm,
+ header=1cm,
+ footer=0cm]
+
+\definehead
+ [directory]
+ [subject]
+
+\setuphead
+ [directory]
+ [style=\tfa]
+
+\setupbodyfont
+ [tt]
+
+\setuptabulate
+ [before=,after=]
+
+\setupcombinations
+ [location=top]
+
+\defineXMLenvironment [files] [root=.,url=]
+ {\doifelsenothing{\XMLop{url}}
+ {\xdef\XMLDIRurl{}}
+ {\xdef\XMLDIRurl{\XMLop{url}/}}
+ \startXMLignore}
+ {\stopXMLignore}
+
+\newcounter\NOfEntries
+
+\startsetups[xmldir:file:normal]
+
+ \doglobal\increment\NOfEntries
+
+ \startfiguretext
+ [left,none]
+ []
+ {}
+ {\hbox
+ {\externalfigure
+ [\XMLpar{files}{root}{.}/\XMLpar{directory}{name}{.}/\XMLop{name}]
+ [frame=on,width=6cm]
+ \quad
+ \framed[width=\figurewidth,height=\figureheight]{}}}
+ \strut \vskip-\lineheight
+ \starttabulate[|l|l|]
+ \NC base \NC \XMLflush{base} \NC \NR
+ \NC type \NC \XMLflush{type} \NC \NR
+ \NC width \NC \figurenaturalwidth \NC \NR
+ \NC height \NC \figurenaturalheight \NC \NR
+ \NC date \NC \XMLflush{date} \NC \NR
+ \NC size \NC \XMLflush{size} \NC \NR
+ \stoptabulate
+ \stopfiguretext
+
+\stopsetups
+
+\startsetups[xmldir:file:small]
+
+ \doglobal\increment\NOfEntries
+
+ \startlinecorrection
+
+ \startcombination
+ {\externalfigure
+ [\XMLpar{files}{root}{.}/\XMLpar{directory}{name}{.}/\XMLop{name}]
+ [frame=on,width=3cm]}
+ {}
+ {\vbox{\starttabulate[|l|l|]
+ \NC base \NC \XMLflush{base} \NC \NR
+ \NC type \NC \XMLflush{type} \NC \NR
+ \NC date \NC \XMLflush{date} \NC \NR
+ \stoptabulate}}
+ {}
+ \stopcombination
+
+ \stoplinecorrection
+
+\stopsetups
+
+\defineXMLenvironment [directory] [name=]
+ {\directory{Path \XMLop{name}}}
+ {}
+
+\defineXMLenvironment [file] [name=]
+ {\bgroup}
+ {% the next quick hack is really needed
+ \expanded{\defconvertedargument\noexpand\asciia{./\jobfilename}.pdf}%
+ \expanded{\defconvertedargument\noexpand\asciib{\XMLpar{directory}{name}{.}/\XMLop{name}}}%
+ % else we can not do an overview of the curent path
+ \doifnot\asciia\asciib
+ {\doifmodeelse{alternative-small}
+ {\setups[xmldir:file:small]}
+ {\setups[xmldir:file:normal]}
+ \endgraf}
+ \egroup}
+
+\defineXMLsave[base]
+\defineXMLsave[type]
+\defineXMLsave[size]
+\defineXMLsave[date]
+
+\starttext
+
+ \doifmode{alternative-small}{\startcolumns[balance=no]}
+
+ \processXMLfilegrouped{\inputfilename}
+
+ \doifmode{alternative-small}{\stopcolumns}
+
+ \ifnum\NOfEntries=0 There are no files found that match the pattern. \fi
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-dir-05.mkii b/tex/context/modules/mkii/x-dir-05.mkii
new file mode 100644
index 000000000..53e73c5eb
--- /dev/null
+++ b/tex/context/modules/mkii/x-dir-05.mkii
@@ -0,0 +1,51 @@
+%D \module
+%D [ file=x-dir-05,
+%D version=2003.05.10, % around that time -)
+%D title=\CONTEXT\ Directory Handling,
+%D subtitle=Access,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setvariables
+ [filestate]
+ [name=,base=,type=,size=,permissions=,date=]
+
+\def\savefilestate
+ {\dodoubleargument\dosavefilestate}
+
+\def\dosavefilestate[#1][#2]%
+ {\startnointerference
+ \setxvariables
+ [#1]
+ [name=#2,base=,type=,size=,permissions=,date=]
+ \executesystemcommand{texmfstart xmltools.rb --dir --pattern=\getvariable{#1}{name} --output=xmldir.tmp}
+ \defineXMLprocess [files]
+ \defineXMLprocess [directory]
+ \defineXMLenvironment [file]
+ {\defineXMLsave [base]
+ \defineXMLsave [type]
+ \defineXMLsave [size]
+ \defineXMLsave [permissions]
+ \defineXMLsave [date]}
+ {\setxvariables
+ [#1]
+ [name=\XMLop{name},
+ base=\XMLflush{base},
+ type=\XMLflush{type},
+ size=\XMLflush{size},
+ permissions=\XMLflush{permissions},
+ date=\XMLflush{date}]}
+ \startXMLignore
+ \processXMLfile{xmldir.tmp}
+ \stopXMLignore
+ \stopnointerference}
+
+\def\getfilestate#1% old one
+ {\savefilestate[filestate][#1]}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-fdf-00.mkii b/tex/context/modules/mkii/x-fdf-00.mkii
new file mode 100644
index 000000000..fd4bea7e7
--- /dev/null
+++ b/tex/context/modules/mkii/x-fdf-00.mkii
@@ -0,0 +1,41 @@
+% <xfdf>
+% <fields>
+% <field name="one">
+% <value>first</value>
+% </field>
+% <field name="two">
+% <value>second</value>
+% </field>
+% </fields>
+% </xfdf>
+%
+% previous method:
+%
+% object
+% data
+% fields
+% field
+
+\defineXMLprocess[fdf:xfdf]
+\defineXMLprocess[fdf:fields]
+\defineXMLignore [fdf:f]
+\defineXMLpush [fdf:value]
+
+\defineXMLenvironment [fdf:field] [name=,value=]
+ {\XMLerase{fdf:value}}
+ {\gsaveXMLdata{fdf:\XMLop{name}}{fdf:value}}
+
+\defineXMLsingular [fdf:field] [name=,value=]
+ {\gsaveXMLasdata{fdf:\XMLop{name}}{\XMLop{value}}}
+
+\def\doifelseFDFfield#1{\doifelseXMLelement{fdf:#1}}
+\def\flushFDFfield #1{\flushXMLelement {fdf:#1}}
+\def\processFDFfield #1{\processXMLelement {fdf:#1}}
+
+\def\loadFDFfile#1%
+ {\bgroup
+ \autoXMLnamespace[fdf]%
+ \processXMLfilegrouped{#1}%
+ \egroup}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-fe.mkii b/tex/context/modules/mkii/x-fe.mkii
new file mode 100644
index 000000000..dcf415850
--- /dev/null
+++ b/tex/context/modules/mkii/x-fe.mkii
@@ -0,0 +1,143 @@
+%D \module
+%D [ file=x-fe,
+%D version=2004.03.12, % based on earlier experiments
+%D title=\FOXET,
+%D subtitle=Simple Extensions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Extensions: fe:definecolor
+
+% menus
+% extra areas
+% protruding and hz
+% compound
+% title container
+% more float placements
+
+\unprotect
+
+% \XMLattributes{aural},
+
+\defineXMLnested
+ [fe:table-next]
+ [id=,
+ \XMLattributes{accessibility},
+ \XMLattributes{border-padding-background},
+ \XMLattributes{relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ visibility=]
+ {\bTABLEnext}
+ {\eTABLEnext}
+
+% definitions
+
+\defineXMLcommand
+ [fe:definecolor]
+ [name=,r=,g=,b=,c=,m=,y=,k=,s=,p=,a=,t=]
+ {\expanded{\definecolor[\XMLop{name}]
+ [r=\XMLop r,g=\XMLop g,b=\XMLop b,
+ c=\XMLop c,m=\XMLop m,y=\XMLop y,k=\XMLop k,
+ s=\XMLop s,p=\XMLop p,a=\XMLop a,t=\XMLop t]}}
+
+\defineXMLcommand
+ [fe:definefontsynonym]
+ [name=,file=,encoding=]
+ {\doifelsenothing{\XMLop{encoding}}
+ {\expanded{\definefontsynonym[\XMLop{name}][\XMLop{file}][encoding=\XMLop{encoding}]}}
+ {\expanded{\definefontsynonym[\XMLop{name}][\XMLop{file}]}}}
+
+%D Extensions: fe:include
+
+\defineXMLsingular
+ [fe:include]
+ [url=,n=1]
+ {\doifelse{\XMLop{n}}{1}
+ {\readfile{\XMLpar{fe:include}{url}{}}{}{}}
+ {\dorecurse{\XMLop{n}}{\readfile{\XMLpar{fe:include}{url}{}}{}{}\endgraf}}}
+
+%D Extensions: fe:sample
+
+\defineXMLenvironment
+ [fe:sample]
+ [origin=unknown]
+ {\removeunwantedspaces\ignorespaces}
+ {\removeunwantedspaces}
+
+%D Extensions: fe:
+
+% \defineXMLenvironmentsave
+% [fe:loop]
+% [n=1]
+% {}
+% {\dorecurse{\XMLop{n}}{\XMLflush{fe:loop}}}
+
+\defineXMLargument
+ [fe:loop]
+ [n=1]
+ {\dorecurse{\XMLop{n}}}
+
+%D Extensions: fe:compound
+
+\defineXMLsingular
+ [fe:compound]
+ [character=-]
+ {\prewordbreak\XMLop{character}\prewordbreak}
+
+%D Extensions: fe:message
+
+\defineXMLargument
+ [fe:message]
+ [category=XML-FO]
+ {\expanded{\writestatus{\XMLop{category}}}}
+
+%D Handy
+
+\defineXMLargument
+ [fe:trace]
+ [attribute=,option=]
+ {\showXMLinh[\XMLop{attribute}]%
+ \XMLval{fe:trace}{\XMLop{option}}{}}
+
+\mapXMLvalue
+ {fe:trace}
+ {font}
+ {\hbox\bgroup\infofont[%
+ \xFOfont/\xFOfontsize/\xFOfontsizeadjust/\xFOfontfamily/\xFOfontweight/\xFOfontstyle/\xFOfontvariant:\FOfontdefinition
+ ]\egroup}
+
+%D Extensions:
+
+\startsetups fe:page:option:fit:start
+ \startTEXpage[margin=page]
+\stopsetups
+
+\startsetups fe:page:option:fit:stop
+ \stopTEXpage
+\stopsetups
+
+\useMPlibrary[pre]
+
+\mapXMLvalue {fe:tracing} {true} {\tracingFOtrue}
+\mapXMLvalue {fe:tracing} {false} {\tracingFOfalse}
+\mapXMLvalue {fe:testgrid} {true} {\setupbackgrounds[page][background=pagegrid]}
+
+\startsetups fe:setup
+ \XMLval{fe:tracing} {\XMLop{fe:tracing}} {}
+ \XMLval{fe:testgrid}{\XMLop{fe:testgrid}}{}
+\stopsetups
+
+%D Private (testing)
+
+\defineXMLcommand[fe:synchronizeoutput]{\synchronizeoutput}
+
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-fig-00.dtd b/tex/context/modules/mkii/x-fig-00.dtd
new file mode 100644
index 000000000..34b4d0bef
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-00.dtd
@@ -0,0 +1,24 @@
+<!-- author : Taco Hoekwater / Hans Hagen
+ info : x-fig-00.tex / x-fig-01.tex
+ usage : <!DOCTYPE figurelibrary SYSTEM "x-fig-00.dtd">
+ -->
+
+<!ELEMENT figurelibrary (description?,figure*)>
+
+<!ATTLIST figurelibrary language CDATA #IMPLIED>
+<!ATTLIST dummy width CDATA #IMPLIED>
+<!ATTLIST dummy height CDATA #IMPLIED>
+
+<!ELEMENT description (organization?,project?,product?,comment?)>
+<!ELEMENT organization (#PCDATA)>
+<!ELEMENT project (#PCDATA)>
+<!ELEMENT product (#PCDATA)>
+
+<!ELEMENT figure (label,file?,dummy?,copyright?,comment?,status?)>
+<!ELEMENT dummy (#PCDATA)>
+<!ELEMENT file (#PCDATA)>
+<!ELEMENT label (#PCDATA)>
+<!ELEMENT copyright (#PCDATA)>
+<!ELEMENT status (#PCDATA)>
+
+<!ELEMENT comment (#PCDATA)>
diff --git a/tex/context/modules/mkii/x-fig-00.mkii b/tex/context/modules/mkii/x-fig-00.mkii
new file mode 100644
index 000000000..2e000c64c
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-00.mkii
@@ -0,0 +1,252 @@
+%D \module
+%D [ file=x-fig-00,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Loading,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \readfile{x-res-04} \donothing \donothing \endinput
+
+% naast label, ook fig als ref en dan naar fig ref springen
+
+%D This module implements an interface to a figure database
+%D and file. The database is formatted in \XML\ conforming
+%D the following \DTD:
+%D
+%D \typefile{x-fig-00.dtd}
+%D
+%D A figure base coded this way looks like:
+%D
+%D \starttyping
+%D <!-- texexec --pdf --use=fig-01 figtest.xml -->
+%D
+%D <figurelibrary language="nl">
+%D
+%D <description>
+%D <organization>PRAGMA Advanced Document Engineering</organization>
+%D <project>Manuals</project>
+%D <product>Beginners Manual</product>
+%D <comment>A bunch of figures.</comment>
+%D </description>
+%D
+%D <figure>
+%D <file>koe.pdf</file>
+%D <label>a dutch cow</label>
+%D <copyright>Corel Draw Suite</copyright>
+%D <comment>I bet that you've seen this cow before.</comment>
+%D </figure>
+%D
+%D <figure>
+%D <dummy width="4cm" height="3cm">non existent</dummy>
+%D <label>a european cow</label>
+%D <copyright>Nobody</copyright>
+%D <comment>When will we talk about European cows?</comment>
+%D </figure>
+%D
+%D </figurelibrary>
+%D \stoptyping
+%D
+%D You can convert this base into a \PDF\ file using
+%D \TEXEXEC\ and another module in this suite.
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-make yourfile.xml
+%D \stoptyping
+%D
+%D You can now select a graphic from this file using the
+%D
+%D \starttyping
+%D \externalfigure[a dutch cow][width=4cm]
+%D \stoptyping
+%D
+%D This module overloads this command so that a figure is
+%D it first searched in the list of databases.
+%D
+%D \starttyping
+%D \usemodule [fig-base]
+%D \usefigurebases[yourfile]
+%D \stoptyping
+%D
+%D The special keyword \type {reset} can be used to reset
+%D this list.
+
+%D We park some mkiv code here. Eventually we will hook this into mkiv
+%D searching differently (just a standard feature, no need for loading
+%D modules because we need less code). Actually, what we do here is more
+%D like res-*: we load the xml file once.
+
+% \startluacode
+%
+% document.figurebases = { }
+% document.figurebases.data = { }
+% document.figurebases.found = { }
+%
+% function document.figurebases.find(basename,askedlabel)
+% document.figurebases.found = { }
+% local base = document.figurebases.data[basename]
+% local page = 0
+% if not base then
+% base = xml.load(basename)
+% document.figurebases.data[basename] = base
+% end
+% for e, d, k in xml.elements(base,"figurelibrary/figure/label") do
+% page = page + 1
+% if xml.content(d[k]) == askedlabel then
+% document.figurebases.found = {
+% name = xml.filters.text(e,"file"),
+% page = page,
+% }
+% return true
+% end
+% end
+% return false
+% end
+%
+% function commands.findfigurefilenameinbase(basename,askedlabel)
+% if document.figurebases.find(basename,askedlabel) then
+% commands.xdef("figurefilename",document.figurebases.found.name or "")
+% commands.xdef("figurefilepage",document.figurebases.found.page or "")
+% end
+% end
+%
+% \stopluacode
+%
+% \def\findfigurefilenameinbase#1#2%
+% {\ctxlua{commands.findfigurefilenameinbase("#1","\askedlabel")}}
+
+\startcommands dutch english
+ german czech
+ italian romanian
+
+ usefigurebase: gebruikfiguurbestand usefigurebase
+ usefigurebase usefigurebase
+ usefigurebase usefigurebase
+
+\stopcommands
+
+\unprotect
+
+\consultutilityfilefalse
+
+\startXMLmapping [-] [figbase]
+
+\defineXMLprocess [figurelibrary]
+\defineXMLignore [description]
+\defineXMLignore [copyright]
+\defineXMLignore [comment]
+\defineXMLignore [status]
+\defineXMLpush [file]
+\defineXMLpush [label]
+\defineXMLpush [dummy]
+\defineXMLenvironment [figure] \figbase@StartFigure \figbase@StopFigure
+
+\stopXMLmapping
+
+\newcounter\figurefilepage
+
+\def\figbase@StartFigure
+ {\bgroup}
+
+\def\figbase@StopFigure
+ {\doglobal\increment\figurefilepage
+ \doif\askedlabel{\XMLpop{label}}
+ {\doglobal\settrue\figurefiledone
+ \xdef\figurefilename{\XMLpop{file}}\endinput}%
+ \egroup}
+
+\def\findfigurefilenameinbase#1#2% sets \figurefilename and \figurefilepage
+ {\processXMLfilegrouped{#1}}
+
+\def\getfigurefilename#1#2%
+ {\startnointerference
+ \traceXMLelementsfalse
+ \startXMLmapping[-][figbase]
+ \resetfigurefilebase
+ \XMLerase{file}
+ \XMLerase{dummy}
+ \XMLerase{label}
+ \xdef\figurefilebase{#1}%
+ \doglobal\newcounter\figurefilepage
+ \def\askedlabel{#2}
+ \processcommacommand[\figurepathlist]\dogetfigurefilename
+ \stopXMLmapping
+ \stopnointerference}
+
+\globalletempty\figurebasepath
+
+\def\dogetfigurefilename#1%
+ {\ifx\figurefilename\empty
+ \bgroup
+ \xdef\figurefilebasepath{#1}%
+ \assignfullfilename{#1}{\figurefilebase}\to\filename
+ \doiffileelse{\filename.xml}
+ {\doshowfigurestate{base file : \filename}%
+ \expanded{\findfigurefilenameinbase{\filename.xml}{\askedlabel}}}
+ \donothing
+ \ifx\figurefilename\empty\else
+% \globallet\figurefilebase\figurefilebase
+ \globallet\figurefilebase\filename % hm, bad omen that this is needed
+ \fi
+ \egroup
+ \fi}
+
+\def\resetfigurefilebase
+ {\globalletempty\figurefilebase
+ \globalletempty\figurefilename
+ \globalletempty\figurefilebasepath
+ \globalletempty\figurefilepage}
+
+\def\doanalyzefiguredimensionsfromfile
+ {\ifcase\figurestatus \ifx\figurebaselist\empty \else
+ \resetfigurefilebase
+ \doshowfigurestate{base list : \figurebaselist}%
+ \processcommacommand[\figurebaselist]\dodoanalyzefiguredimensionsfromfile
+ \ifx\figurefilename\empty
+ \doshowfigurestate{base warning : no matching name found}%
+ \else
+ \doiffileelse{\figurefilebase.pdf}
+ {\doshowfigurestate{base file : \figurefilebase.pdf}%
+ \doshowfigurestate{base page : \figurefilepage}%
+ \let\figurepathlist\figurefilebasepath
+ \analyzefigurefilename{\figurefilebase.pdf}\wantedfigurelabel
+ \let\wantedfigurepage\figurefilepage}
+ {\doshowfigurestate{base missing : \figurefilebase.pdf}}
+ \fi
+ \ifcase\figurestatus
+ \analyzefigurefilename\expandedfigurename\wantedfigurelabel
+ \fi
+ \fi \fi}
+
+\def\dodoanalyzefiguredimensionsfromfile#1%
+ {\doshowfigurestate{base check : \wantedfigurename\space in #1}%
+ \getfigurefilename{#1}\wantedfigurename
+ \ifx\figurefilename\empty\else
+ \quitcommalist
+ \fi}
+
+\def\usefigurebase[#1]%
+ {\doifelse{#1}\v!reset
+ {\let\figurebaselist\empty}
+ {\addtocommalist{#1}\figurebaselist}}
+
+\let\figurebaselist\empty
+
+\resetfigurefilebase
+
+\protect \endinput
+
+\usefigurebase[figtest]
+
+\externalfigure[koetje] [width=3cm]
+\externalfigure[de molen op de dijk][width=3cm]
+\externalfigure[de molen op de dijk][width=2cm]
+\externalfigure[weet ik veel] [width=3cm]
+\externalfigure[weet ik veel] [width=2cm]
+\externalfigure[weet ik wat] [width=2cm]
+\externalfigure[koe] [width=2cm]
diff --git a/tex/context/modules/mkii/x-fig-00.xsd b/tex/context/modules/mkii/x-fig-00.xsd
new file mode 100644
index 000000000..615841a1e
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-00.xsd
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ <p>This schema described the figure database. This base
+ can be used to collect graphics that later can be used
+ in applications like ConTeXt.</p>
+ <p>author: Tobias Burnus &amp; Hans Hagen, copyright:
+ PRAGMA-ADE / Hasselt NL</p>
+ </xsd:documentation>
+</xsd:annotation>
+
+<xsd:element name="figurelibrary" type="figureLibraryType" />
+
+<xsd:element name="comment" type="nonZeroString" />
+
+<xsd:complexType name="figureLibraryType">
+ <xsd:sequence>
+ <xsd:element name="description" type="descriptionType" />
+ <xsd:element name="figure" type="figureType"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="language" type="xsd:language" />
+</xsd:complexType>
+
+<xsd:complexType name="descriptionType">
+ <xsd:sequence>
+ <xsd:element name="organization" type="nonZeroString" />
+ <xsd:element name="project" type="nonZeroString" />
+ <xsd:element name="product" type="nonZeroString" />
+ <xsd:element ref="comment" minOccurs="0" />
+ </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="figureType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="file" type="NZNormalizedString" />
+ <xsd:element name="dummy" type="dummyType" />
+ </xsd:choice>
+ <xsd:element name="label" type="NZNormalizedString" />
+ <xsd:element name="copyright" type="nonZeroString" />
+ <xsd:element ref="comment" minOccurs="0" />
+ </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="dummyType">
+ <xsd:simpleContent>
+ <xsd:extension base="nonZeroString">
+ <xsd:attribute name="width" type="TeXUnit" use="required" />
+ <xsd:attribute name="height" type="TeXUnit" use="required" />
+ </xsd:extension>
+ </xsd:simpleContent>
+</xsd:complexType>
+
+<xsd:simpleType name="nonZeroString">
+ <xsd:restriction base="xsd:string">
+ <xsd:minLength value="1" />
+ </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:simpleType name="NZNormalizedString">
+ <xsd:restriction base="xsd:normalizedString">
+ <xsd:minLength value="1" />
+ </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:simpleType name="TeXUnit">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern
+ value='[0-9]*(,|\.|[0-9])?[0-9]*(cm|mm|in|pt|pc|em|ex|bp|dd|cc|sp)' />
+ </xsd:restriction>
+</xsd:simpleType>
+
+</xsd:schema>
diff --git a/tex/context/modules/mkii/x-fig-01.mkii b/tex/context/modules/mkii/x-fig-01.mkii
new file mode 100644
index 000000000..5a2ea20c8
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-01.mkii
@@ -0,0 +1,461 @@
+%D \module
+%D [ file=x-fig-01,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \readfile {x-res-01} \donothing \donothing \endinput
+
+%D See \type {x-fig-00.tex} for more information on how to use
+%D and generate figure databases. This file loads the file
+%D named \type {\jobfilename} (\TEXEXEC\ will set this
+%D variable). You can apply this style to a database by
+%D saying:
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-make yourfile.xml
+%D \stoptyping
+%D
+%D The following modes are supported:
+%D
+%D \starttabulate[|lT|l|]
+%D \NC letter \NC map the preview on letter size \NC \NR
+%D \NC compact \NC use an alternative presentation \NC \NR
+%D \stoptabulate
+%D
+%D The resulting file has the following characteristics:
+%D
+%D \startitemize[packed]
+%D \item the document is split into three sections: first each
+%D figure is shown at its own page, then an overview of
+%D figures is shown with some data alongside, and
+%D finally an index and table of contents shows up
+%D \item there is no title page, which means that one can
+%D access a figure by page number without offset
+%D \item the document is opened at the first overview page,
+%D that is, when the viewer supports it
+%D \item the graphic is shown 3~times: on a page of its own,
+%D scaled to a fixed dimension, and relative to a4 or
+%D letter paper size
+%D \item the labels can be accessed in an index and list at
+%D the end of the document
+%D \stopitemize
+%D
+%D We use named destinations, which means that one can
+%D access a figure by name from an external application.
+
+\usemodule[fig-00]
+
+\setupoutput[pdftex] \overcomePDFspacefalse
+
+\doifnothing {\jobfilename} {\end}
+\doiffileelse {\jobfilename.xml} {} {\end}
+
+\definesymbol [attachment] [{\bf\color[darkred]{\jobname.xml}}]
+\setupattachments [symbol=attachment]
+\useattachment [datafile] [\jobname.xml]
+
+\def\StartDescription
+ {\bgroup
+ \defineXMLpush[organization]
+ \defineXMLpush[project]
+ \defineXMLpush[product]
+ \defineXMLpush[comment]}
+
+\def\StopDescription
+ {\subject {Figure collection}
+ \starttabulate[|lBe|p|]
+ \doifXMLdataelse{organization}
+ {\NC organization \NC \XMLpop{organization} \NC \NR}{}
+ \doifXMLdataelse{project}
+ {\NC project \NC \XMLpop{project} \NC \NR}{}
+ \doifXMLdataelse{product}
+ {\NC product \NC \XMLpop{product} \NC \NR}{}
+ \doifXMLdataelse{comment}
+ {\NC comment \NC \XMLpop{comment} \NC \NR}{}
+ \NC specification \NC \attachment[datafile] \NC \NR
+ \stoptabulate
+ \blank[2*big]
+ \egroup}
+
+\def\StartFigureA
+ {\bgroup
+ \defineXMLpush[file]
+ \XMLassign{file}{buffer}
+ \defineXMLpush[dummy]
+ \defineXMLpush[label]
+ \defineXMLpush[copyright]
+ \defineXMLpush[comment]
+ \defineXMLpush[status]}
+
+\defineoverlay[page][\overlaybutton{Description}]
+
+\startbuffer
+ \framed
+ [width=\XMLpar{dummy}{width}{12cm},
+ height=\XMLpar{dummy}{height}{8cm},
+ background=color,
+ backgroundcolor=gray,
+ foregroundcolor=darkred,
+ frame=off]
+ {\bf \XMLpop{dummy}}
+\stopbuffer
+
+\def\StopFigureA
+ {\doglobal\increment\CurrentPage
+ \setupbackgrounds[page][background=page]
+ \doifelsenothing{\XMLpop{label}}
+ {\expanded{\definereference[Description][about: \XMLpop{file}]}%
+ \pagereference[\XMLpop{file}]}
+ {\expanded{\definereference[Description][about: \XMLpop{label}]}%
+ \pagereference[\XMLpop{label}]}
+ \pagefigure[\XMLpop{file}]
+ \setupbackgrounds[page][background=]
+ \egroup}
+
+\def\StartFigureB
+ {\StartFigureA}
+
+\defineregister
+ [figureindex]
+ [figureindices]
+
+\setupregister
+ [figureindex]
+ [ownnumber=yes,
+ criterium=text,
+ interaction=text,
+ indicator=no]
+
+\definelist
+ [figurelist]
+
+\setuplist
+ [figurelist]
+ [criterium=text,
+ pagenumber=no,
+ width=2em,
+ interaction=all]
+
+\setupcolors
+ [state=start]
+
+\setuptolerance
+ [verytolerant]
+
+% Ugly:
+
+\startnotmode[previewpage-letter,previewpage-S6]
+ \enablemode[previewpage-A4]
+\stopnotmode
+
+\startmode[letter] % downward compatible
+ \enablemode[previewpage-letter]
+\stopmode
+
+%startbuffer[paper]
+\startsetups[paper]
+\startmode[previewpage-A4]
+ \framed
+ [width=210mm,height=297mm,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLpop{file}][reset=yes]}
+\stopmode
+\startmode[previewpage-letter]
+ \framed
+ [width=8.5in,height=11in,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLpop{file}][reset=yes]}
+\stopmode
+\startmode[previewpage-S6]
+ \framed
+ [width=600pt,height=450pt,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLpop{file}][reset=yes]}
+\stopmode
+\stopsetups
+%stopbuffer
+
+\setupbuttons
+ [offset=10pt,
+ width=broad,
+ strut=no,
+ rulethickness=1pt,
+ framecolor=darkred]
+
+\def\StopFigureB
+ {\par
+ \doglobal\increment\CurrentPage
+ \doifelsenothing{\XMLpop{label}}
+ {\expanded{\definereference[Figure][\XMLpop{file}]}%
+ \expanded{\definereference[GridPg][grid:\XMLpop{file}]}}
+ {\expanded{\definereference[Figure][\XMLpop{label}]}%
+ \expanded{\definereference[GridPg][grid:\XMLpop{label}]}}%
+ \button % content in setup
+ {\hbox to \hsize
+ {\forgetall \dontcomplain
+ \doifelsenothing{\XMLpop{label}}
+ {\pagereference[about: \XMLpop{file}]}
+ {\pagereference[about: \XMLpop{label}]}%
+ % moved here, because descriptions may be absent
+ \ifnum\CurrentPage=1 \pagereference[begin]\fi
+ %
+ \expanded{\writetolist[figurelist]{\CurrentPage}{\XMLpop{label}}}%
+ \expanded{\figureindex{\CurrentPage}{\XMLpop{label}}}%
+ \startnotmode[compact]%
+ \vbox to 100pt
+ {\hsize30pt
+ \vskip5pt
+ \hbox to \hsize{\hss\strut\bf\CurrentPage\hss}%
+ \vfill}%
+ \advance\hsize by -30pt
+ \stopnotmode
+ \startmode[compact]%
+ \advance\hsize by -10pt
+ \hskip10pt
+ \stopmode
+ \button % \framed
+ [width=150pt,height=100pt,offset=10pt,frame=off,
+ background=color,backgroundcolor=white,color=]
+ {\externalfigure
+ [\XMLpop{file}]
+ [maxheight=80pt,frame=off,maxwidth=130pt,factor=max]}%
+ [GridPg]%
+ \let\FigWid\figurenaturalwidth
+ \let\FigHei\figurenaturalheight
+ \advance\hsize by -150pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt
+ {\hsize40pt
+ %\externalfigure
+ % [paper]
+ % [type=buffer,frame=on,
+ % framecolor=darkred,rulethickness=.5pt,
+ % width=40pt,object=no]
+ \framed
+ [offset=overlay,
+ framecolor=darkred,
+ rulethickness=.5pt]
+ {\scale[width=40pt]{\setups[paper]}}% {\disableXML\getbuffer[paper]}}%
+ \startmode[compact]%
+ \vfill
+ \hbox to \hsize{\hss\strut\bf\CurrentPage\hss}%
+ \stopmode
+ \vfill}%
+ \advance\hsize by -40pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt
+ {\blank[disable]
+ \starttabulate[|Bel|p|]
+ \NC file \NC \XMLpop{file} \NC \NR
+ \doifXMLdata{label}
+ {\NC label \NC \XMLpop{label} \NC \NR}
+ \NC w$\times$h \NC \FigWid$\times$\FigHei \NC \NR
+ \doifXMLdata{copyright}
+ {\NC copyright \NC \XMLpop{copyright} \NC \NR}
+ \doifXMLdata{status}
+ {\doifelse{\XMLpop{status}}{obsolete}
+ {\NC status \NC \bf\darkred\XMLpop{status} \NC \NR}
+ {\NC status \NC \XMLpop{status} \NC \NR}}
+ \doifXMLdata{comment}
+ {\NC comment \NC \XMLpop{comment} \NC \NR}
+ \stoptabulate
+ \vfill}}}%
+ [Figure]
+ \vskip10pt
+ \egroup}
+
+\def\StartFigureC
+ {\StartFigureA}
+
+\def\StopFigureC
+ {\doglobal\increment\NumberOfFigures
+ \egroup}
+
+\setuplayout
+ [topspace=15pt,backspace=15pt,
+ header=0pt,footer=0pt,bottom=20pt,bottomdistance=10pt,
+ width=middle,height=fit]
+
+\setupbackgrounds
+ [page]
+ [background=,
+ backgroundcolor=gray]
+
+\setupinteractionscreen
+ [width=max,
+ height=max]
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [style=,
+ color=,
+ contrastcolor=,
+ state=start]
+
+\setuphead
+ [section]
+ [style=bfb]
+
+\setupbodyfont
+ [pos]
+
+\setupinteractionmenu
+ [bottom]
+ [left=\hfill,
+ middle=\hskip10pt,
+ frame=off,
+ style=bold,
+ background=color,
+ backgroundcolor=darkred,
+ foregroundcolor=white]
+
+\startinteractionmenu[bottom]
+ \but [begin] begin \\
+ \but [index] index \\
+ \but [list] list \\
+ \but [CloseDocument] close \\
+ \but [PreviousJump] go back \\
+\stopinteractionmenu
+
+\setupinteraction
+ [openaction=begin]
+
+\defineXMLenvironment [figurelibrary] \StartLibrary \StopLibrary
+
+\starttext
+
+\def\StartLibrary{\mainlanguage[\XMLpar{figurelibrary}{language}{en}]}
+\def\StopLibrary {}
+
+\defineXMLignore [description]
+\defineXMLenvironment [figure] \StartFigureC \StopFigureC
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfilename.xml}
+
+\increment\NumberOfFigures
+
+\defineXMLignore [description]
+\defineXMLenvironment [figure] \StartFigureA \StopFigureA
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfilename.xml}
+
+\setuppapersize
+ [S6][S6]
+
+\setupbackgrounds
+ [page]
+ [background=color]
+
+\setupinteraction
+ [menu=on]
+
+\defineXMLenvironment [description] \StartDescription \StopDescription
+\defineXMLenvironment [figure] \StartFigureB \StopFigureB
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfilename.xml} \page
+
+\subject [list] {List of figures}
+
+\placelist[figurelist] \page
+
+\subject [index] {Index of figures}
+
+\startcolumns
+\placeregister[figureindex]
+\stopcolumns
+
+\doifmodeelse{clipgrid-distance,clipgrid-steps}{\page}{\stoptext}
+
+\startuniqueMPgraphic{clipgrid}{dx,dy,nx,ny,type}
+ numeric gdx, gdy, lbx, lby ;
+ if \MPvar{type}=1 :
+ gdx := \MPvar{dy} ;
+ gdy := \MPvar{dx} ;
+ else :
+ gdx := OverlayWidth /\MPvar{nx} ;
+ gdy := OverlayHeight/\MPvar{ny} ;
+ fi ;
+ lbx := gdx ;
+ lby := gdy ;
+ defaultfont := "\truefontname{Mono}" ;
+ defaultscale := .5 ;
+ numeric pen ; pen := .25pt ;
+ def MyGrid text t =
+ draw vlingrid (0,OverlayWidth ,gdy,OverlayWidth ,OverlayHeight) t ;
+ draw hlingrid (0,OverlayHeight,gdx,OverlayHeight,OverlayWidth ) t ;
+ enddef ;
+ pickup pencircle scaled pen ;
+ MyGrid withcolor white ;
+ MyGrid dashed evenly scaled pen ;
+ draw OverlayBox withcolor white ;
+ draw OverlayBox dashed evenly scaled pen ;
+ draw vlinlabel.bot(0,eps+OverlayWidth /lby,2,OverlayWidth ) ;
+ draw hlinlabel.lft(0,eps+OverlayHeight/lbx,2,OverlayHeight) ;
+ setbounds currentpicture to OverlayBox enlarged (2*EmWidth) ;
+\stopuniqueMPgraphic
+
+\presetMPvariable[clipgrid][dx=10pt]
+\presetMPvariable[clipgrid][dy=10pt]
+\presetMPvariable[clipgrid][nx=10]
+\presetMPvariable[clipgrid][ny=10]
+
+\startmode[clipgrid-distance]
+ \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=1}]
+\stopmode
+
+\startmode[clipgrid-steps]
+ \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=2}]
+\stopmode
+
+\setupexternalfigures
+ [background={color,foreground,grid},
+ backgroundcolor=white]
+
+\def\StartFigureD
+ {\StartFigureA}
+
+\def\StopFigureD
+ {\doglobal\increment\CurrentPage
+ \setupbackgrounds[page][background=page]
+ \startpagefigure[\XMLpop{file}][offset=20pt]%
+ \doifelsenothing{\XMLpop{label}}
+ {\expanded{\definereference[Description][about: \XMLpop{file}]}%
+ \pagereference[grid:\XMLpop{file}]}
+ {\expanded{\definereference[Description][about: \XMLpop{label}]}%
+ \pagereference[grid:\XMLpop{label}]}
+ \stoppagefigure
+ %\pagefigure[\XMLpop{file}][offset=20pt]
+ \setupbackgrounds[page][background=]
+ \egroup}
+
+\defineXMLignore
+ [description]
+
+\defineXMLenvironment
+ [figure]
+ \StartFigureD
+ \StopFigureD
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfilename.xml} \page
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-fig-02.mkii b/tex/context/modules/mkii/x-fig-02.mkii
new file mode 100644
index 000000000..a8232fba9
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-02.mkii
@@ -0,0 +1,78 @@
+%D \module
+%D [ file=x-fig-02,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Inclusion (I),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \readfile {x-res-02} \donothing \donothing \endinput
+
+%D This module enables non||\ConTeXt\ users to access the
+%D database. For this, you need to run
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-fake yourfile.xml
+%D \stoptyping
+%D
+%D The resulting file, \type {yourfile.fig}, can be loaded
+%D in the normal way. The figures can be accessed with:
+%D
+%D \starttyping
+%D \getfigurefile{label}
+%D \getfigurepage{label}
+%D \stoptyping
+%D
+%D A a bonus, the following macro is defined:
+%D
+%D \starttyping
+%D \includefigurefile width 10cm {label}
+%D \stoptyping
+
+\usemodule[fig-00]
+
+\doifnothing {\jobfilename} {\end}
+\doiffileelse {\jobfilename.xml} {} {\end}
+
+\defineXMLenvironment [figurelibrary] \StartLibrary \StopLibrary
+\defineXMLignore [description]
+\defineXMLenvironment [figure] \StartFigure \StopFigure
+
+\def\StartLibrary
+ {\immediate\openout \scratchwrite=\jobfilename.fig
+ \immediate\write\scratchwrite{\string\input\space x-fig-03.tex \string\relax}
+ \immediate\write\scratchwrite{}}
+
+\def\StopLibrary
+ {\immediate\write\scratchwrite{}
+ \immediate\write\scratchwrite{\string\endinput}
+ \immediate\closeout\scratchwrite}
+
+\def\StartFigure
+ {\defineXMLpush[file]
+ \defineXMLpush[dummy]
+ \defineXMLpush[label]
+ \defineXMLpush[copyright]
+ \defineXMLpush[comment]
+ \defineXMLpush[status]}
+
+\def\StopFigure
+ {\doglobal\increment\CurrentPage
+ \immediate\write\scratchwrite
+ {\string\setfiguredata\space
+ {\XMLpop{label}}
+ {\jobfilename}
+ {\CurrentPage}}}
+
+\doglobal\newcounter\CurrentPage
+
+\starttext
+
+\processXMLfilegrouped{\jobfilename.xml}
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-fig-03.mkii b/tex/context/modules/mkii/x-fig-03.mkii
new file mode 100644
index 000000000..c7f03453e
--- /dev/null
+++ b/tex/context/modules/mkii/x-fig-03.mkii
@@ -0,0 +1,44 @@
+%D \module
+%D [ file=x-fig-03,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Inclusion (II),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifx \undefined \convertMPtoPDF \input supp-pdf.mkii \fi
+\ifx \undefined \includefigurefile \else \expandafter \endinput \fi
+
+\gdef\getfigurefile#1%
+ {\expandafter\ifx\csname x-fig-f-#1\endcsname\relax
+ \currentfigurefile
+ \else
+ \csname x-fig-f-#1\endcsname
+ \fi}
+
+\gdef\getfigurepage#1%
+ {\expandafter\ifx\csname x-fig-p-#1\endcsname\relax
+ 1%
+ \else
+ \csname x-fig-p-#1\endcsname
+ \fi}
+
+\gdef\setfiguredata#1#2#3%
+ {\gdef\currentfigurefile{#2}%
+ \expandafter\gdef\csname x-fig-f-#1\endcsname{#2}%
+ \expandafter\gdef\csname x-fig-p-#1\endcsname{#3}}
+
+\def\includefigurefile#1#%
+ {\doincludefigurefile{#1}}
+
+\def\doincludefigurefile#1#2%
+ {\edef\next{\noexpand\pdfimage
+ #1 page \getfigurepage{#2} {\getfigurefile{#2}.pdf}}%
+ \next}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-fo.mkii b/tex/context/modules/mkii/x-fo.mkii
new file mode 100644
index 000000000..2c1ac0d96
--- /dev/null
+++ b/tex/context/modules/mkii/x-fo.mkii
@@ -0,0 +1,4057 @@
+%D \module
+%D [ file=x-fo,
+%D version=2004.03.12, % based on earlier experiments
+%D title=\FOXET,
+%D subtitle=Formatting Objects,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \showframe
+
+% This is a first implementation, maybe I will write another one with mixed
+% element indifferent vars and something 'when set, act upon it, and forget',
+% for instance: in each element check if font set, if so, change font and
+% reset font attributes. I'm not sure if this is wise.
+
+% todo: global assignment in order to limit restore
+% todo: combine mp graphics (see end) saves 30%
+% todo: using contants and variables (for internal use)
+
+% todo: language at more levels
+
+% beware: aftergroup vs egroup/endgroup
+
+\useXMLfilter[prs,run]
+
+\unprotect
+
+% syst-new.tex
+
+\long\def\unstringed#1% " ' space
+ {\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1}
+
+\long\setvalue{@u@s@"}#1#2"{#2}
+\long\setvalue{@u@s@'}#1#2'{#2}
+\long\setvalue{@u@s@ }#1#2 {#2}
+
+% xtag-ini
+
+\def\letXMLpar #1#2{\@EA \let\csname\@@XMLvariable:#1:#2\endcsname}
+\def\setXMLpar #1#2{\@EA \def\csname\@@XMLvariable:#1:#2\endcsname}
+\def\setXMLepar#1#2{\@EA\edef\csname\@@XMLvariable:#1:#2\endcsname}
+
+\protect
+
+%D Most time went into figuring out the specifications, especially
+%D because there are no examples included. Samples that circulate on the
+%D web are often border cases and torture test and don't have much to do
+%D with real live. Another complication lays in the inheritance model:
+%D some of the attributes are inherited. This also leaves some room for
+%D interpretation, for instance do values that are used at a certain
+%D point migrate downwards or not.
+%D
+%D The \CONTEXT\ \XML handler can deal with attributes in several ways
+%D and for this purpose I have played with a few experimental mechanisms
+%D just to end up with the existing begin/end mechanism combined with
+%D a recursive attribute resolver which means that one has to implicitly
+%D ask for an inherited attributes. This approach is probably one of the
+%D most efficient ways of dealing with formatting objects in \CONTEXT,
+%D unless of course I start adding rather specific support to the kernel.
+%D
+%D This module is rather experimental. More information about its usage
+%D can be found in the \FOXET\ manual.
+
+%D Since we're not dealing with the fine points of typesetting here, we
+%D can safely ignore \TEX's warnings about overful or underful boxes.
+
+\dontcomplain
+
+%D We will use fonts that have the characters in the normal (ascii)
+%D slots. We will also use the stupid verbatim handler.
+
+\chardef\XMLtokensreduction = 2
+\chardef\XMLcdatamethod = 2
+
+%D For the purpose of testing.
+
+\startmode[fo-verbose]
+ \def\writeFOstatus{\writestatus{XML-FO}}
+\stopmode
+
+\startnotmode[fo-verbose]
+ \let\writeFOstatus\gobbleoneargument
+\stopnotmode
+
+%D For the moment we stick to utf-8.
+
+\useXMLfilter[utf]
+
+%D This will be sorted out later (esp in relation to mathml).
+
+\setupbodyfont[pos,10pt]
+
+%D There are a couple of predefined colors. Don't ask me why, but
+%D formatting objects are not a fresh start but a mix of existing
+%D technologies. Color support is poluted by cascading stylesheets.
+%D
+%D Because hexadecimal color specifications are not enabled by
+%D default, this feature has to be enables by loading the appropriate
+%D color module. Here we define colors in \RGB\ values because we
+%D don't want to loose accuracy.
+
+\setupcolors[state=start] \setupcolor[hex]
+
+\definecolor [black] [s=0] % [h=000000]
+\definecolor [gray] [s=.5] % [h=808080]
+\definecolor [silver] [s=.75] % [h=C0C0C0]
+\definecolor [white] [s=1] % [h=FFFFFF]
+\definecolor [maroon] [r=.5] % [h=800000]
+\definecolor [red] [r=1] % [h=FF0000]
+\definecolor [purple] [r=.5,b=.5] % [h=800080]
+\definecolor [fuchsia] [r=1,b=1] % [h=FF00FF]
+\definecolor [green] [g=.5] % [h=008000]
+\definecolor [lime] [g=1] % [h=00FF00]
+\definecolor [olive] [r=.5,g=.5] % [h=808000]
+\definecolor [yellow] [r=1,g=1] % [h=FFFF00]
+\definecolor [navy] [r=1,g=1] % [h=000080]
+\definecolor [blue] [b=1] % [h=0000FF]
+\definecolor [teal] [g=.5,b=.5] % [h=008080]
+\definecolor [aqua] [g=1,b=1] % [h=00FFFF]
+
+%D The layout is rather basic. Of the 25 available areas we
+%D only use the text area. Maybe some day I will plug in a
+%D more dedicated page builder.
+
+\setuplayout
+ [backspace=0pt,
+ topspace=0pt,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle,
+ % marking=on,
+ location=middle]
+
+\setuppagenumbering
+ [alternative={doublesided,singlesided}, % sic
+ location=]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+%D We will position the regions using layers.
+
+\definelayer[regions][width=\paperwidth,height=\paperheight]
+
+\definelayer[xsl-region-before]
+\definelayer[xsl-region-after]
+\definelayer[xsl-region-start]
+\definelayer[xsl-region-end]
+\definelayer[xsl-region-body]
+
+\setupbackgrounds[page][background=regions]
+
+%D We now enter the part of this module where the action takes
+%D place. As usual we provide some tracing options.
+
+\newif\iftracingFO \readsysfile{page-run}\donothing\donothing
+
+%D We will organize the attribute definitions in a similar fashion as in
+%D the specification. Unfortunately there are more sets defined in there
+%D than are actually used, so the definitions later on will look a bit
+%D messy.
+%D
+%D Quite some attributes can be inherited, which means that they can
+%D end up in all elements and influence those way down the tree.
+
+\defineXMLattributeset
+ [fo:inherited]
+
+%D The properties:
+
+% \defineXMLattributeset
+% [fe:tracing]
+% [tracing=]
+
+\defineXMLattributeset
+ [fo:accessibility]
+ [source-document=none,
+ role=none]
+
+\defineXMLattributeset
+ [fo:absolute-position]
+ [absolute-position=auto,
+ top=auto,
+ right=auto,
+ bottom=auto,
+ left=auto]
+
+% \defineXMLattributeset
+% [fo:aural]
+% [azitmuth=,
+% cue-after=,
+% cue-before=,
+% elevation=,
+% pause-after=,
+% pause-before=,
+% pitch=,
+% pitch-range=,
+% play-during=,
+% richness=,
+% speak=,
+% speak-header=,
+% speak-numeral=,
+% speak-punctuation=,
+% speech-rate=,
+% stress=,
+% voice-family=,
+% volume=]
+
+\defineXMLattributeset
+ [fo:border-padding-background]
+ [background-attachment=scroll,
+ background-color=transparent,
+ background-image=none,
+ background-repeat=repeat,
+ background-position-horizontal=left,
+ background-position-vertical=top,
+ border-color=transparent,
+ border-style=none,
+ border-width=medium,
+ background-position=,
+ border-top=,
+ border-bottom=,
+ border-left=,
+ border-right=,
+ border-before-color=\XMLop{border-color},
+ border-before-style=\XMLop{border-style},
+ border-before-width=\XMLop{border-width},
+ border-after-color=\XMLop{border-color},
+ border-after-style=\XMLop{border-style},
+ border-after-width=\XMLop{border-width},
+ border-start-color=\XMLop{border-color},
+ border-start-style=\XMLop{border-style},
+ border-start-width=\XMLop{border-width},
+ border-end-color=\XMLop{border-color},
+ border-end-style=\XMLop{border-style},
+ border-end-width=\XMLop{border-width},
+ border-top-color=\XMLop{border-before-color},
+ border-top-style=\XMLop{border-before-style},
+ border-top-width=\XMLop{border-before-width},
+ border-bottom-color=\XMLop{border-after-color},
+ border-bottom-style=\XMLop{border-after-style},
+ border-bottom-width=\XMLop{border-after-width},
+ border-left-color=\XMLop{border-start-color},
+ border-left-style=\XMLop{border-start-style},
+ border-left-width=\XMLop{border-start-width},
+ border-right-color=\XMLop{border-end-color},
+ border-right-style=\XMLop{border-end-style},
+ border-right-width=\XMLop{border-end-width},
+ padding=,% 0pt,
+ padding-before=0pt,%\XMLop{padding},
+ padding-after=0pt,%\XMLop{padding},
+ padding-start=0pt,%\XMLop{padding},
+ padding-end=0pt,%\XMLop{padding},
+ padding-top=\XMLop{padding-before},
+ padding-bottom=\XMLop{padding-after},
+ padding-left=\XMLop{padding-start},
+ padding-right=\XMLop{padding-end}]
+
+\extendXMLattributeset
+ [fo:border-padding-background]
+ [fe:background-height=,
+ fe:background-width=]
+
+\defineXMLattributeset
+ [fo:font]
+ []
+
+\extendXMLattributeset
+ [fo:inherited]
+ [font=,
+ font-family=,% Times,
+ font-selection-strategy=,
+ font-size=,% 12pt,
+ font-size-adjust=, % 1,
+ font-style=, % normal,
+ font-variant=, % normal,
+ font-weight=] % normal]
+
+\defineXMLattributeset
+ [fo:hyphenation]
+ []
+
+\extendXMLattributeset
+ [fo:inherited]
+ [country=,
+ language=,
+ script=,
+ hyphenate=,
+ hyphenation-character=,
+ hyphenation-push-character-count=,
+ hyphenation-remain-character-count=]
+
+\defineXMLattributeset
+ [fo:margin-block]
+ [margin=, % 0pt,
+ margin-top=0pt,% \XMLop{margin},
+ margin-bottom=0pt,% \XMLop{margin},
+ margin-left=0pt,% \XMLop{margin},
+ margin-right=0pt,% \XMLop{margin},
+ space-before=0pt,
+ space-after=0pt,
+ space-before.precedence=,
+ space-before.conditionality=,
+ space-before.minimum=,
+ space-before.optimum=,
+ space-before.maximum=,
+ space-after.precedence=,
+ space-after.conditionality=,
+ space-after.minimum=,
+ space-after.optimum=,
+ space-after.maximum=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [start-indent=,
+ end-indent=]
+
+\defineXMLattributeset
+ [fo:margin-inline]
+ [space-start=,
+ space-end=]
+
+\defineXMLattributeset
+ [fo:relative-position]
+ [relative-position=,
+ top=auto,
+ right=auto,
+ bottom=auto,
+ left=auto]
+
+\defineXMLattributeset
+ [fo:area-alignment]
+ [alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ dominant-baseline=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [display-align=,
+ relative-align=]
+
+\defineXMLattributeset
+ [fo:area-dimension]
+ [block-progression-dimension=,
+ inline-progression-dimension=,
+ content-height=,
+ content-width=,
+ height=,
+ width=,
+ max-height=,
+ max-width=,
+ min-height=,
+ min-width=,
+ scaling=,
+ scaling-method=]
+
+\defineXMLattributeset
+ [fo:block-and-line]
+ []
+
+\extendXMLattributeset
+ [fo:inherited]
+ [hyphenation-keep=,
+ hyphenation-ladder-count=,
+ last-line-end-indent=,
+ line-height=,
+ line-height-shift-adjustment=,
+ line-stacking-strategy=,
+ linefeed-treatment=,
+ white-space-treatment=,
+ text-align=,
+ text-align-last=,
+ text-indent=,
+ white-space-collapse=,
+ wrap-option=]
+
+\defineXMLattributeset
+ [fo:character]
+ [character=,
+ suppress-at-line-break=,
+ text-decoration=,
+ text-shadow=,
+ treat-as-word-space=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [letter-spacing=,
+ text-transform=,
+ word-spacing=]
+
+\defineXMLattributeset
+ [fo:color]
+ [color-profile-name=,
+ rendering-intent=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [color=]
+
+\defineXMLattributeset
+ [fo:float]
+ [clear=,
+ float=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [intrusion-displace=]
+
+\defineXMLattributeset
+ [fo:keeps-and-breaks]
+ [break-after=,
+ break-before=,
+ keep-with-next.within-line=,
+ keep-with-next.within-column=,
+ keep-with-next.within-page=,
+ keep-with-previous.within-line=,
+ keep-with-previous.within-column=,
+ keep-with-previous.within-page=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [keep-together.within-line=,
+ keep-together.within-column=,
+ keep-together.within-page=,
+ orphans=,
+ widows=]
+
+\defineXMLattributeset
+ [fo:layout]
+ [clip=,
+ overflow=
+ span=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [reference-orientation=]
+
+\defineXMLattributeset
+ [fo:leader-and-rule]
+ []
+
+\extendXMLattributeset
+ [fo:inherited]
+ [leader-alignment=,
+ leader-pattern=,
+ leader-pattern-width=,
+ leader-pattern-width=,
+ leader-length=,
+ rule-style=,
+ rule-thickness=]
+
+\defineXMLattributeset
+ [fo:dynamic-effects]
+ [active-state=,
+ case-name=,
+ case-title=,
+ destination-placement-offset=,
+ external-destination=,
+ indicate-destination=,
+ internal-destination=,
+ show-destination=,
+ starting-state=,
+ switch-to=,
+ target-presentation-context=,
+ target-processing-context=,
+ target-stylesheet=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [auto-restore=]
+
+\defineXMLattributeset
+ [fo:markers]
+ [marker-class-name=,
+ retrieve-class-name=,
+ retrieve-position=,
+ retrieve-boundary=]
+
+\defineXMLattributeset
+ [fo:number-to-string]
+ [country=,
+ language=,
+ format=,
+ grouping-separator=,
+ grouping-size=,
+ letter-value=]
+
+% \defineXMLattributeset
+% [fo:pagination-and-layout]
+% [black-or-not-blank=,
+% column-count=1,
+% column-gap=12pt,
+% extent=,
+% flow-name=,
+% force-page-count=,
+% initial-page-number=,
+% master-name=,
+% master-reference=,
+% maximum-repeats=,
+% media-usage=,
+% odd-or-even=,
+% page-height=,
+% page-position=,
+% page-width=,
+% precedence=,
+% region-name=]
+
+\defineXMLattributeset
+ [fo:table]
+ [border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ column-number=,
+ column-width=,
+ ends-row=,
+ number-columns-repeated=,
+ number-columns-spanned=,
+ number-rows-spanned=,
+ starts-row=,
+ table-layout=,
+ table-omit-footer-at-break=,
+ table-omit-header-at-break=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [border-collapse=,
+ border-separation=,
+ caption-side=,
+ empty-cells=]
+
+\defineXMLattributeset
+ [fo:writing-mode]
+ [%text-altitude=,
+ %text-depth=,
+ unicode-bidi=]
+
+\extendXMLattributeset % for practical reasons we inherit along the whole chain
+ [fo:inherited] % unless we implement relax skipping
+ [text-altitude=,
+ text-depth=]
+
+\extendXMLattributeset
+ [fo:inherited]
+ [direction=,
+ glyph-orientation-horizontal=,
+ glyph-orientation-vertical=,
+ writing-mode=]
+
+\defineXMLattributeset
+ [fo:list-block]
+ []
+
+\extendXMLattributeset
+ [fo:inherited]
+ [provisional-label-separation=,
+ provisional-distance-between-starts=]
+
+% \starttext
+% \setuplayout[topspace=1cm,height=middle,header=0pt,footer=0pt]
+% \setupbodyfont[small,tt]
+% \expanded{\processcommalist[\XMLattributeset{fo:inherited}]}\endgraf
+% \stoptext
+
+% content-type
+% id
+
+% ref-id
+% score-spaces % inherited
+% src
+% visibility % inherited
+% z-index
+
+% shorthands:
+%
+% background
+% background-position
+% border
+% border-bottom
+% border-left
+% border-top
+% border-right
+% border-style
+% border-color
+% border-spacing % inherited
+% border-width
+% cue
+% font % inherited
+% margin
+% padding
+% page-break-after
+% page-break-before
+% page-break-inside % inherited
+% pause
+% position
+% size
+% vertical-align
+% white-space % inherited
+
+%D We will speed up the process of setting up attributes by compiling the
+%D definitions. Sometimes we need to access attributes explicitly by
+%D element (for instance when handling regions). We also need to deal
+%D with nested elements (for instance blocks) or a sequence of similar
+%D ones, while we may not always want to use grouping. As a result, the
+%D next series of definitions and macros are quite ugly. The begin|/|end
+%D is needed in order to comfortably fetch attribute values from
+%D ancestors.
+
+\startXMLcompiling[inherit]
+
+%D Element: fo:root
+
+%D todo: set defaults here
+
+\defineXMLenvironment
+ [fo:root]
+ [\XMLattributeset{fo:inherited},
+leader-pattern=spaces,
+leader-pattern-width=12pt,
+ media-usage=]
+ {\directsetup{fo:root:start}}
+ {\directsetup{fo:root:stop}}
+
+\startsetups fo:root:start
+ \starttext \beginXMLelement \startXMLignore
+ \doifsomething{\XMLop{language}}{\mainlanguage[\XMLop{language}]}% todo, everywhere
+\stopsetups
+
+\startsetups fo:root:stop
+ \stopXMLignore \endXMLelement \stoptext
+\stopsetups
+
+%D Element: fo:declarations
+
+\defineXMLprocess
+ [fo:declarations]
+
+%D Element: fo:color-profile
+
+\defineXMLignore
+ [fo:color-profile]
+ [src=,
+ color-profile-name=,
+ rendering-intent=]
+
+%D Element: fo:page-sequence
+
+% master-name and master-reference are often mixed up in examples
+
+\defineXMLenvironment
+ [fo:page-sequence]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:number-to-string},
+ initial-page-number=auto,
+ master-reference=any,
+ force-page-count=auto]
+ {\beginXMLelement\directsetup{fo:page-sequence:start}}
+ {\directsetup{fo:page-sequence:stop}\endXMLelement}
+
+\mapXMLvalue {fo:page-initial} {auto} {\relax}
+\mapXMLvalue {fo:page-initial} {auto-odd} {\ifodd\pageno \expanded{\setuppagenumber[number=\the\dimexpr(\pageno+1)]}\fi}
+\mapXMLvalue {fo:page-initial} {auto-even} {\ifodd\pageno\else\expanded{\setuppagenumber[number=\the\dimexpr(\pageno+1)]}\fi}
+
+% todo: blokkeer left/right/etc in geval van blank
+
+\mapXMLvalue {fo:page-start} {auto} {\page}
+\mapXMLvalue {fo:page-start} {even} {\page\setuplayout[blank]\page[even]}
+\mapXMLvalue {fo:page-start} {odd} {\page\setuplayout[blank]\page[odd]}
+\mapXMLvalue {fo:page-end} {end-on-even} {\page\setuplayout[blank]\page[even]}
+\mapXMLvalue {fo:page-end} {end-on-odd} {\page\setuplayout[blank]\page[odd]}
+\mapXMLvalue {fo:page-start} {no-force} {\page}
+
+\startsetups fo:page-sequence:start
+
+ % we're still in the previous page-sequence
+
+ \XMLval{fo:page-start}{\XMLop{force-page-count}}{\page} \begingroup
+
+ \directsetup{fe:setup}
+
+ \iftracingFO \showframe[text] \fi
+
+ \xdef\SavedPageNumber{\the\realpageno}
+
+ % now we enter the new page-sequence
+
+ % todo: check on number
+
+ \doifXMLvalelse{fo:page-initial}{\XMLop{initial-page-number}}
+ {\XMLval{fo:page-initial}{\XMLop{initial-page-number}}{}}
+ {\doifnot{\XMLop{initial-page-number}}{auto}
+ {\expanded{\setuppagenumber[number=\XMLop{initial-page-number}]}}}
+
+ \doifsomething{\XMLpar{fo:page-sequence}{master-reference}{}}
+ {\doifelseXMLelement{fo:page-sequence-master:\XMLpar{fo:page-sequence}{master-reference}{}}
+ {%[starting page sequence master: \XMLpar{fo:page-sequence}{master-reference}{}]\endgraf
+ \flushXMLelement{fo:page-sequence-master:\XMLpar{fo:page-sequence}{master-reference}{}}}
+ {%[starting simple page master: \XMLpar{fo:page-sequence}{master-reference}{any}]\endgraf
+ \flushXMLelement{fo:simple-page-master:\XMLpar{fo:page-sequence}{master-reference}{any}}}}
+
+ \doif{\XMLpar{fo:simple-page-master-do}{fe:option}{}}{fit}
+ {\directsetup{fe:page:option:fit:start}}
+
+ \doifnot{\XMLpar{fo:region-body}{column-count}{1}}{1}
+ {\directsetup{fo:columns:start}}
+
+\stopsetups
+
+\startsetups fo:page-sequence:stop
+
+ \doifnot{\XMLpar{fo:region-body}{column-count}{1}}{1}
+ {\directsetup{fo:columns:stop}}
+
+ \doif{\XMLpar{fo:simple-page-master-do}{fe:option}{}}{fit}
+ {\directsetup{fe:page:option:fit:stop}}
+
+ % \XMLval{fo:page-end}{\XMLop{force-page-count}}{\page} \endgroup
+
+ \ifnum\SavedPageNumber=\realpageno
+
+ \ifdim\pagetotal<.5\textheight \null \vfill \fi % force a page with only containers
+
+ \fi
+
+ \XMLval{fo:page-end}{\XMLpar{fo:page-sequence}{force-page-count}{}}{\page} \endgroup
+
+\stopsetups
+
+\newdimen\FOcolumngap
+
+\startsetups fo:columns:start
+
+ \FOcolumngap\textwidth
+
+ \setpercentdimen\FOcolumngap{\XMLpar{fo:region-body}{column-gap}{12pt}}
+
+ % we need to freeze the lineheight here
+
+ \expanded{\definecolumnset
+ [fo:set]
+ [n=\XMLpar{fo:region-body}{column-count}{1},
+ distance=\FOcolumngap]}
+
+ \expanded{\definecolumnsetspan
+ [fo:set]
+ [n=\XMLpar{fo:region-body}{column-count}{1}]}
+
+ \directsetup{fo:font:setup} % else problems
+
+ \directsetup{fo:line-height:setup}
+
+% \parseXMLattributes{fo:flow}{line-height='normal'}
+
+ \startcolumnset[fo:set]
+
+ % \startcolumns[\XMLpar{fo:region-body}{column-count}{1}]
+
+\stopsetups
+
+\startsetups fo:columns:stop
+
+ % \stopcolumns
+
+ \stopcolumnset
+
+\stopsetups
+
+%D Element: fo:layout-master-set
+
+\defineXMLprocess
+ [fo:layout-master-set]
+
+%D Element: fo:page-sequence-master
+
+\defineXMLenvironmentsave
+ [fo:page-sequence-master]
+ [\XMLattributeset{fo:inherited},
+ master-name=any]
+ {}
+ {%[saved page sequence master: \XMLop{master-name}]\endgraf
+ \gsaveXMLdatainelement
+ {fo:page-sequence-master:\XMLop{master-name}}
+ {fo:page-sequence-master-do}
+ {fo:page-sequence-master}}
+
+\defineXMLprocess
+ [fo:page-sequence-master-do]
+ [\XMLattributeset{fo:inherited}]
+
+%D Element: fo:single-page-master-reference
+
+% makeup - one page
+
+\defineXMLcommand
+ [fo:single-page-master-reference]
+ [master-reference=any]
+ {\flushXMLelement{fo:simple-page-master:\XMLop{master-reference}}}
+
+%D Element: fo:repeatable-page-master-reference
+
+\defineXMLcommand
+ [fo:repeatable-page-master-reference]
+ [master-reference=any,
+ maximum-repeats=]
+ {\flushXMLelement{fo:simple-page-master:\XMLop{master-reference}}}
+
+%D Element: fo:repeatable-page-master-alternatives
+
+\defineXMLprocess
+ [fo:repeatable-page-master-alternatives]
+ [maximum-repeats=]
+
+%D Element: fo:conditional-page-master-reference
+
+% page-position : first last rest any
+% odd-or-even : odd even any
+% blank-or-not-blank : blank not-blank
+
+% The page-position default is needed (else possible loops)
+
+\defineXMLcommand
+ [fo:conditional-page-master-reference]
+ [master-reference=any,
+ page-position=\XMLpar{fo:conditional-page-master-reference}{master-reference}{any},
+ blank-or-not-blank=,
+ odd-or-even=]
+ {\flushXMLelement{fo:simple-page-master:\XMLpar{fo:conditional-page-master-reference}{master-reference}{}}}
+
+%D Element: fo:simple-page-master
+
+% first-page left-page right-page blank-page
+
+% default dimensions
+
+\defineXMLenvironmentsave
+ [fo:simple-page-master]
+ [master-name=any]
+ {}
+ {%[saved simple page master: \XMLop{master-name}]\endgraf
+ \gsaveXMLdatainelement
+ {fo:simple-page-master:\XMLop{master-name}}
+ {fo:simple-page-master-do}
+ {fo:simple-page-master}}
+
+% reference-orientation=0deg,
+% writing-mode=
+
+\defineXMLenvironment
+ [fo:simple-page-master-do]
+ [\XMLattributeset{fo:inherited}, % added
+ \XMLattributeset{fo:margin-block},
+ page-height=29.7cm,
+ page-width=21cm]
+ {\directsetup{fo:simple-page-master:start}}
+ {\directsetup{fo:simple-page-master:stop}}
+
+% not needed any more:
+
+\mapXMLvalue {fo:reference-orientation} {0deg} {0}
+\mapXMLvalue {fo:reference-orientation} {90deg} {90}
+\mapXMLvalue {fo:reference-orientation} {180deg} {180}
+\mapXMLvalue {fo:reference-orientation} {270deg} {270}
+\mapXMLvalue {fo:reference-orientation} {-90deg} {270}
+\mapXMLvalue {fo:reference-orientation} {-180deg} {180}
+\mapXMLvalue {fo:reference-orientation} {-270deg} {90}
+
+\startsetups fo:simple-page-master:start
+
+ % nothing
+
+\stopsetups
+
+% can be low level tex
+
+\startsetups fo:simple-page-master:stop
+
+ \writeFOstatus{defining papersize '\directsetup{fo:layout:kind}'}
+
+ \expanded
+ {\definepapersize
+ [\directsetup{fo:layout:kind}]
+ [width=\XMLop{page-width},
+ height=\XMLop{page-height}]}
+
+ \checkFOpadding {fo:region-body}
+ \checkFOmargin {fo:region-body}
+ \checkFOmargin {fo:simple-page-master-do}
+
+ \writeFOstatus{defining layout '\directsetup{fo:layout:kind}'}
+
+ \FOscratchMT\paperheight \setpercentdimen\FOscratchMT{\XMLpar{fo:simple-page-master-do}{margin-top} \zeropoint}
+ \FOscratchMB\paperheight \setpercentdimen\FOscratchMB{\XMLpar{fo:simple-page-master-do}{margin-bottom}\zeropoint}
+ \FOscratchML\paperwidth \setpercentdimen\FOscratchML{\XMLpar{fo:simple-page-master-do}{margin-left} \zeropoint}
+ \FOscratchMR\paperwidth \setpercentdimen\FOscratchMR{\XMLpar{fo:simple-page-master-do}{margin-right} \zeropoint}
+
+ \FOscratchRB\paperheight \setpercentdimen\FOscratchRB{\XMLpar{fo:region-body}{margin-top} \zeropoint}
+ \FOscratchRA\paperheight \setpercentdimen\FOscratchRA{\XMLpar{fo:region-body}{margin-bottom}\zeropoint}
+ \FOscratchRS\paperwidth \setpercentdimen\FOscratchRS{\XMLpar{fo:region-body}{margin-left} \zeropoint}
+ \FOscratchRE\paperwidth \setpercentdimen\FOscratchRE{\XMLpar{fo:region-body}{margin-right} \zeropoint}
+
+ \FOscratchPB\paperheight \setpercentdimen\FOscratchPB{\XMLpar{fo:region-body}{padding-top} \zeropoint}
+ \FOscratchPA\paperheight \setpercentdimen\FOscratchPA{\XMLpar{fo:region-body}{padding-bottom}\zeropoint}
+ \FOscratchPS\paperwidth \setpercentdimen\FOscratchPS{\XMLpar{fo:region-body}{padding-left} \zeropoint}
+ \FOscratchPE\paperwidth \setpercentdimen\FOscratchPE{\XMLpar{fo:region-body}{padding-right} \zeropoint}
+
+ \expanded
+ {\definelayout
+ [\directsetup{fo:layout:kind}]
+ [ page={\directsetup{fo:layout:kind},\XMLval{fo:reference-orientation}{\XMLop{reference-orientation}}{}},
+ paper=\directsetup{fo:layout:kind},
+ backspace=\the\dimexpr(\FOscratchML+\FOscratchPS+\FOscratchRS),
+ cutspace=\the\dimexpr(\FOscratchMR+\FOscratchPE+\FOscratchRE),
+ topspace=\the\dimexpr(\FOscratchMT+\FOscratchPB+\FOscratchRB),
+ bottomspace=\the\dimexpr(\FOscratchMB+\FOscratchPA+\FOscratchRA)]}
+
+ \expanded{\setuplayout[\directsetup{fo:layout:kind}]}
+
+ % this is a nasty bit of code: this local setup stores some data that
+ % needs to be used later
+
+ \startexpanded
+ \noexpand \startlocalsetups[layout:\directsetup{fo:layout:kind}]
+ \noexpand \writeFOstatus{processing simple page master '\XMLpar{fo:simple-page-master-do}{master-name}{any}'}
+ \noexpand \resetsetups[fo:simple-page-master:start]
+ \noexpand \resetsetups[fo:simple-page-master:stop]
+ \noexpand \flushXMLelement{fo:simple-page-master:\XMLpar{fo:simple-page-master-do}{master-name}{any}}
+ \noexpand \stoplocalsetups
+ \stopexpanded
+
+\stopsetups
+
+% \defineXMLcommand[fo:simple-page-master-do-do]
+% {\writeFOstatus{setting up master \XMLop{master-name} in page body}}
+
+%D Element: fo:region-body
+
+% display-align=,
+% reference-orientation=,
+% writing-mode=,
+
+\defineXMLcommand % or process
+ [fo:region-body]
+ [\XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ fe:z-order=above,
+ clip=,
+ column-count=1,
+ column-gap=12pt,
+ overflow=,
+ region-name=]
+ {\directsetup{fo:region-body:process}}
+
+\startsetups fo:region-body:process
+ \writeFOstatus{refreshing region-body parameters}
+\stopsetups
+
+% todo: naar realfolio handelen ipv folio
+
+\mapXMLvalue {fo:odd-or-even} {odd} {odd}
+\mapXMLvalue {fo:odd-or-even} {even} {even}
+
+\mapXMLvalue {fo:page-position} {any} {rest} % todo
+\mapXMLvalue {fo:page-position} {first} {current}
+\mapXMLvalue {fo:page-position} {last} {last} % todo
+\mapXMLvalue {fo:page-position} {rest} {rest} % todo
+
+%mapXMLvalue {fo:blank-or-not-blank} {any} {} % todo
+%mapXMLvalue {fo:blank-or-not-blank} {not-blank} {} % todo
+%mapXMLvalue {fo:blank-or-not-blank} {blank} {} % todo
+
+% check this one esp default value
+
+\startsetups fo:layout:kind
+
+ \XMLpav
+ {fo:odd-or-even}
+ {fo:conditional-page-master-reference}
+ {odd-or-even}
+ {\XMLpav
+ {fo:page-position}
+ {fo:conditional-page-master-reference}
+ {page-position}
+ {\XMLpar{fo:page-sequence-master}{master-reference}{any}}}
+
+\stopsetups
+
+% common border things
+
+% clip
+% display-align
+% extent
+% overflow
+% precedence
+% region-name
+% reference-orientation
+% writing-mode
+
+%D Element: fo:region-before fo:region-after fo:region-start fo:region-end
+
+% border-before-color : <color> | inherit
+% border-before-style : <border style> | inherit
+% border-before-width.length|conditional : <border width> | <length conditional> | inherit
+%
+% style: none hidden dotted dashed solid double groove ridge inset outset
+% width: thin medium thick length
+
+\mapXMLvalue {fo:display-align} {auto} {before} % todo: related to relative-align
+\mapXMLvalue {fo:display-align} {before} {high}
+\mapXMLvalue {fo:display-align} {after} {low}
+\mapXMLvalue {fo:display-align} {center} {lohi}
+
+% display-align=,
+% reference-orientation=,
+% writing-mode=,
+
+\defineXMLcommand % will become process when stable
+ [fo:region-before]
+ [\XMLattributeset{fo:border-padding-background},
+ clip=,
+ extent=,
+ overflow=,
+ precedence=,
+ region-name=]
+ {\directsetup{fo:region-before:process}}
+
+\startsetups fo:region-before:process
+ \writeFOstatus{refreshing region-before parameters}
+\stopsetups
+
+\defineXMLprocess
+ [fo:region-after]
+ [\XMLattributeset{fo:border-padding-background},
+ clip=,
+ extent=,
+ overflow=,
+ precedence=,
+ region-name=]
+
+\defineXMLprocess
+ [fo:region-start]
+ [\XMLattributeset{fo:border-padding-background},
+ clip=,
+ extent=,
+ overflow=,
+ region-name=]
+
+\defineXMLprocess
+ [fo:region-end]
+ [\XMLattributeset{fo:border-padding-background},
+ clip=,
+ extent=,
+ overflow=,
+ region-name=]
+
+\mapXMLvalue {fo:border-style} {none} {0}
+\mapXMLvalue {fo:border-style} {hidden} {1}
+\mapXMLvalue {fo:border-style} {dotted} {2}
+\mapXMLvalue {fo:border-style} {dashed} {3}
+\mapXMLvalue {fo:border-style} {solid} {4}
+\mapXMLvalue {fo:border-style} {double} {5}
+\mapXMLvalue {fo:border-style} {groove} {6}
+\mapXMLvalue {fo:border-style} {ridge} {7}
+\mapXMLvalue {fo:border-style} {inset} {8}
+\mapXMLvalue {fo:border-style} {outset} {9}
+
+\mapXMLvalue {fo:border-width} {thin} {.25pt}
+\mapXMLvalue {fo:border-width} {medium} {.5pt}
+\mapXMLvalue {fo:border-width} {thick} {1pt}
+
+\startsetups fo:regions:check
+
+ \startprocesscommalist[body,before,after,start,end]
+
+ \checkFOborder{fo:region-\currentcommalistitem}{bottom}
+ \checkFOborder{fo:region-\currentcommalistitem}{top}
+ \checkFOborder{fo:region-\currentcommalistitem}{left}
+ \checkFOborder{fo:region-\currentcommalistitem}{right}
+
+ \checkhexcolor[\XMLpar{fo:region-\currentcommalistitem}{border-bottom-color}{}]
+ \checkhexcolor[\XMLpar{fo:region-\currentcommalistitem}{border-top-color}{}]
+ \checkhexcolor[\XMLpar{fo:region-\currentcommalistitem}{border-left-color}{}]
+ \checkhexcolor[\XMLpar{fo:region-\currentcommalistitem}{border-right-color}{}]
+ \checkhexcolor[\XMLpar{fo:region-\currentcommalistitem}{background-color}{}]
+
+ \checkFOposition{fo:region-\currentcommalistitem}{background}
+ \checkFOpadding {fo:region-\currentcommalistitem}
+ \checkFOmargin {fo:region-\currentcommalistitem}
+
+ \stopprocesscommalist
+
+\stopsetups
+
+%D Element: fo:flow
+
+\defineXMLenvironment
+ [fo:flow]
+ [\XMLattributeset{fo:inherited},
+ flow-name=unknown]
+ {\beginXMLelement\directsetup{fo:flow:start}}
+ {\directsetup{fo:flow:stop}\endXMLelement}
+
+\startsetups fo:flow:start
+ \begingroup
+\stopsetups
+
+\startsetups fo:flow:stop
+ \endgroup
+\stopsetups
+
+%D Element: fo:static-content
+
+% \beginXMLelement \endXMLelement - maybe save with attributes
+
+\defineXMLenvironmentsave
+ [fo:static-content]
+ [flow-name=unknown]
+ {}
+ {\directsetup{fo:static-content:process}}
+
+\startsetups fo:static-content:process
+
+ \gsaveXMLdata{fo:static-content:\XMLop{flow-name}}{fo:static-content}
+
+\stopsetups
+
+\newdimen\FOscratchML \newdimen\FOscratchMR \newdimen\FOscratchMT \newdimen\FOscratchMB
+\newdimen\FOscratchPB \newdimen\FOscratchPA \newdimen\FOscratchPS \newdimen\FOscratchPE
+\newdimen\FOscratchRB \newdimen\FOscratchRA \newdimen\FOscratchRS \newdimen\FOscratchRE
+
+\mapXMLvalue {fo:background-repeat} {no-repeat} {0}
+\mapXMLvalue {fo:background-repeat} {repeat} {1}
+\mapXMLvalue {fo:background-repeat} {repeat-x} {2}
+\mapXMLvalue {fo:background-repeat} {repeat-y} {3}
+
+\expanded {\mapXMLvalue {fo:background-location} {left} {0\letterpercent}}
+\expanded {\mapXMLvalue {fo:background-location} {right} {100\letterpercent}}
+\expanded {\mapXMLvalue {fo:background-location} {top} {0\letterpercent}}
+\expanded {\mapXMLvalue {fo:background-location} {bottom} {100\letterpercent}}
+\expanded {\mapXMLvalue {fo:background-location} {center} {50\letterpercent}}
+
+\newdimen\FObgpositionH
+\newdimen\FObgpositionV
+
+\def\FObackgroundimage#1#2#3%
+ {\doifnot{\XMLpar{fo:#1}{background-image}{none}}{none}
+ {\setFOimagename{\XMLpar{fo:#1}{background-image}{dummy}}%
+ \FObgpositionH#2%
+ \setpercentdimen\FObgpositionH{\XMLpav
+ {fo:background-location}
+ {fo:#1}
+ {background-position-horizontal}
+ {\XMLpar{fo:#1}{background-position-horizontal}{}}}%
+ \ifpercentdimendone
+ \skip0\zeropoint plus \FObgpositionH
+ \skip2\zeropoint plus \dimexpr(#2-\FObgpositionH)%
+ \else
+ \skip0\FObgpositionH
+ \skip2\zeropoint plus 1fill\relax
+ \fi
+ \FObgpositionV#3%
+ \setpercentdimen\FObgpositionV{\XMLpav
+ {fo:background-location}{fo:#1}{background-position-vertical}
+ {\XMLpar{fo:#1}{background-position-vertical}{}}}%
+ \ifpercentdimendone
+ \skip4\zeropoint plus \FObgpositionV
+ \skip6\zeropoint plus \dimexpr(#3-\FObgpositionV)%
+ \else
+ \skip4\FObgpositionV
+ \skip6\zeropoint plus 1fill\relax
+ \fi
+ \vbox to #3 \bgroup
+ \vskip\skip4\relax
+ \hbox to #2 \bgroup
+ \hskip\skip0\relax
+ \backgroundimage
+ {\XMLpav{fo:background-repeat}{fo:#1}{background-repeat}{}}{#2}{#3}%
+ {\externalfigure
+ [\FOimagename]
+ [width=\XMLpar{fo:#1}{fe:background-width}{},
+ height=\XMLpar{fo:#1}{fe:background-height}{}]}%
+ \hskip\skip2\relax
+ \egroup
+ \vskip\skip6\relax
+ \egroup}}
+
+\def\checkFOclipping#1%
+ {\doifsomething{\XMLpar{#1}{clip}{}}
+ {\analyzefunction{\XMLpar{#1}{clip}{}}%
+ \doif\functionname{rect}
+ {\def\postprocessframebox##1%
+ {\edef\next{\dimen0=\the\wd##1\dimen2=\the\ht##1\dimen4=\the\dp##1}%
+ \setbox##1\hbox
+ {\clip % expanded?
+ [topoffset=-\functionA,
+ bottomoffset=-\functionC,
+ leftoffset=-\functionD,
+ rightoffset=-\functionB]
+ {\box##1}}%
+ \next}}}}
+
+\def\clipFOarea#1%
+ {\doifsomething{\XMLpar{#1}{clip}{}}%
+ {\analyzefunction{\XMLpar{#1}{clip}{}}%
+ \doif\functionname{rect}
+ {\setbox\scratchbox\hbox{\foregroundbox}%
+ \edef\next{\dimen0=\the\wd\scratchbox\dimen2=\the\ht\scratchbox\dimen4=\the\dp\scratchbox}%
+ \setbox\scratchbox\hbox
+ {\clip % expanded?
+ [topoffset=-\functionA,
+ bottomoffset=-\functionC,
+ leftoffset=-\functionD,
+ rightoffset=-\functionB]
+ {\box\scratchbox}}%
+ \next
+ \box\scratchbox}}}
+
+\defineoverlay
+ [text]
+ [\clipFOarea{fo:region-body}]
+
+\setupbackgrounds
+ [text]
+ [background=text]
+
+\def\FOregionbuilder#1#2#3#4#5#6% #1=location #2=preset #3=x #4=y #5=width #6=height
+ {\writeFOstatus{building region #1}%
+ \defineoverlay
+ [image]
+ [{\framed
+ [frame=off,
+ orientation=\XMLpav{fo:reference-orientation}{fo:#1}{reference-orientation}{0},
+ offset=overlay,
+ height=\overlayheight,
+ width=\overlaywidth]
+ {\FObackgroundimage{#1}\hsize\vsize}}]%
+ \setlayerframed
+ [regions]
+ [preset=#2,x=\dimexpr(#3),y=\dimexpr(#4)]
+ [frame=off,
+ offset=overlay,background={#1-graphic,image,xsl-#1},
+ width=\dimexpr(#5),height=\dimexpr(#6)]
+ {\lrtbbox
+ {\XMLpar{fo:#1}{padding-left}\zeropoint}%
+ {\XMLpar{fo:#1}{padding-right}\zeropoint}%
+ {\XMLpar{fo:#1}{padding-top}\zeropoint}%
+ {\XMLpar{fo:#1}{padding-bottom}\zeropoint}%
+ {\checkFOclipping{fo:#1}%
+ \framed
+ [frame=off,
+ offset=overlay,
+ orientation=\XMLpav{fo:reference-orientation}{fo:#1}{reference-orientation}{0},
+ align={\XMLpav{fo:display-align}{fo:#1}{display-align}{high},\XMLpav{fo:align-key}{fo:#1}{text-align}{normal}},
+ width=\hsize,height=\vsize]
+ {\doFObeforeskip{fo:#1}%
+ \flushXMLelement{fo:static-content:\XMLpar{fo:#1}{region-name}{xsl-#1}}}%
+ \doFOafterskip{fo:#1}}}}
+
+\startsetups fo:regions:process
+
+ \directsetup{fo:regions:check}
+
+ \checkFOmargin{fo:simple-page-master-do}
+
+ \FOscratchMT\paperheight \setpercentdimen\FOscratchMT{\XMLpar{fo:simple-page-master-do}{margin-top} \zeropoint}
+ \FOscratchMB\paperheight \setpercentdimen\FOscratchMB{\XMLpar{fo:simple-page-master-do}{margin-bottom}\zeropoint}
+ \FOscratchML\paperwidth \setpercentdimen\FOscratchML{\XMLpar{fo:simple-page-master-do}{margin-left} \zeropoint}
+ \FOscratchMR\paperwidth \setpercentdimen\FOscratchMR{\XMLpar{fo:simple-page-master-do}{margin-right} \zeropoint}
+
+ \doif{\XMLpar{fo:region-body}{fe:z-order}{above}}{below}{\directsetup{fo:regions:process:body}}
+
+ \FOscratchRB\paperheight \setpercentdimen\FOscratchRB{\XMLpar{fo:region-before}{extent}\zeropoint}
+ \FOscratchRA\paperheight \setpercentdimen\FOscratchRA{\XMLpar{fo:region-after} {extent}\zeropoint}
+ \FOscratchRS\paperwidth \setpercentdimen\FOscratchRS{\XMLpar{fo:region-start} {extent}\zeropoint}
+ \FOscratchRE\paperwidth \setpercentdimen\FOscratchRE{\XMLpar{fo:region-end} {extent}\zeropoint}
+
+ \doifelse{\XMLpar{fo:region-before}{precedence}{false}}{true}
+ {\doifelse{\XMLpar{fo:region-after}{precedence}{false}}{true}
+ {\directsetup{fo:regions:process:true:true}}
+ {\directsetup{fo:regions:process:true:false}}}
+ {\doifelse{\XMLpar{fo:region-after}{precedence}{false}}{true}
+ {\directsetup{fo:regions:process:false:true}}
+ {\directsetup{fo:regions:process:false:false}}}
+
+ \doif{\XMLpar{fo:region-body}{fe:z-order}{above}}{above}{\directsetup{fo:regions:process:body}}
+
+\stopsetups
+
+\newdimen\FOscratchEB
+\newdimen\FOscratchEA
+
+\chardef\FOregionmode\zerocount
+
+\startmode[fo-pt]
+ \chardef\FOregionmode\plusone % fotex mode -)
+\stopmode
+
+\startsetups fo:regions:modes
+
+ \ifcase\FOregionmode
+ \FOscratchEB\zeropoint
+ \FOscratchEA\zeropoint
+ \or
+ \FOscratchEB\paperheight \setpercentdimen\FOscratchEB{\XMLpar{fo:region-before}{extent}\zeropoint}
+ \FOscratchEA\paperheight \setpercentdimen\FOscratchEA{\XMLpar{fo:region-after} {extent}\zeropoint}
+ \else
+ \FOscratchEB\zeropoint
+ \FOscratchEA\zeropoint
+ \fi
+
+\stopsetups
+
+\startsetups fo:regions:process:body
+
+ \bgroup
+
+ \FOscratchRB\paperheight \setpercentdimen\FOscratchRB{\XMLpar{fo:region-body}{margin-top} \zeropoint}
+ \FOscratchRA\paperheight \setpercentdimen\FOscratchRA{\XMLpar{fo:region-body}{margin-bottom}\zeropoint}
+ \FOscratchRS\paperwidth \setpercentdimen\FOscratchRS{\XMLpar{fo:region-body}{margin-left} \zeropoint}
+ \FOscratchRE\paperwidth \setpercentdimen\FOscratchRE{\XMLpar{fo:region-body}{margin-right} \zeropoint}
+
+ \FOregionbuilder
+ {region-body}
+ {lefttop}
+ {\FOscratchML+\FOscratchRS}
+ {\FOscratchMT+\FOscratchRA}
+ {\paperwidth -\FOscratchML-\FOscratchMR-\FOscratchRS-\FOscratchRE}
+ {\paperheight-\FOscratchMT-\FOscratchMB-\FOscratchRB-\FOscratchRA}
+
+ \egroup
+
+\stopsetups
+
+\startsetups fo:regions:process:true:true
+
+ \directsetup{fo:regions:modes}
+
+ \ifdim\FOscratchRB>\zeropoint \FOregionbuilder
+ {region-before}{lefttop}
+ {\FOscratchML}{\FOscratchMT-\FOscratchEB}
+ {\paperwidth-\FOscratchML-\FOscratchMR}{\FOscratchRB}
+ \fi \ifdim\FOscratchRA>\zeropoint \FOregionbuilder
+ {region-after}{leftbottom}
+ {\FOscratchML}{\FOscratchMB-\FOscratchEA}
+ {\paperwidth-\FOscratchML-\FOscratchMR}{\FOscratchRA}
+ \fi \ifdim\FOscratchRS>\zeropoint \FOregionbuilder
+ {region-start}{lefttop}
+ {\FOscratchML}{\FOscratchMT+\FOscratchRB}
+ {\FOscratchRS}{\paperheight-\FOscratchMT-\FOscratchMB-\FOscratchRA-\FOscratchRB}
+ \fi \ifdim\FOscratchRE>\zeropoint \FOregionbuilder
+ {region-end}{righttop}
+ {\FOscratchMR}{\FOscratchMT+\FOscratchRA}
+ {\FOscratchRE}{\paperheight-\FOscratchMT-\FOscratchMB-\FOscratchRA-\FOscratchRB}
+ \fi
+
+\stopsetups
+
+\startsetups fo:regions:process:false:true
+
+ \directsetup{fo:regions:modes}
+
+ \ifdim\FOscratchRB>\zeropoint \FOregionbuilder
+ {region-before}{lefttop}
+ {\FOscratchML+\FOscratchRS}{\FOscratchMT-\FOscratchEB}
+ {\paperwidth-\FOscratchML-\FOscratchMR-\FOscratchRS-\FOscratchRE}{\FOscratchRB}
+ \fi \ifdim\FOscratchRA>\zeropoint \FOregionbuilder
+ {region-after}{leftbottom}
+ {\FOscratchML}{\FOscratchMB-\FOscratchEA}
+ {\paperwidth-\FOscratchML-\FOscratchMR}{\FOscratchRA}
+ \fi \ifdim\FOscratchRS>\zeropoint \FOregionbuilder
+ {region-start}{lefttop}
+ {\FOscratchML}{\FOscratchMT}
+ {\FOscratchRS}{\paperheight-\FOscratchMB-\FOscratchRA-\FOscratchRB}
+ \fi \ifdim\FOscratchRE>\zeropoint \FOregionbuilder
+ {region-end}{righttop}
+ {\FOscratchMR}{\FOscratchMT}
+ {\FOscratchRE}{\paperheight-\FOscratchMB-\FOscratchRA-\FOscratchRB}
+ \fi
+
+\stopsetups
+
+\startsetups fo:regions:process:true:false
+
+ \directsetup{fo:regions:modes}
+
+ \ifdim\FOscratchRB>\zeropoint \FOregionbuilder
+ {region-before}{lefttop}
+ {\FOscratchML}{\FOscratchMT-\FOscratchEB}
+ {\paperwidth-\FOscratchML-\FOscratchMR}{\FOscratchRB}
+ \fi \ifdim\FOscratchRA>\zeropoint \FOregionbuilder
+ {region-after}{leftbottom}
+ {\FOscratchML+\FOscratchRS}{\FOscratchMB-\FOscratchEA}
+ {\paperwidth-\FOscratchML-\FOscratchMR-\FOscratchRS-\FOscratchRE}{\FOscratchRA}
+ \fi \ifdim\FOscratchRS>\zeropoint \FOregionbuilder
+ {region-start}{lefttop}
+ {\FOscratchML}{\FOscratchMT+\FOscratchRB}
+ {\FOscratchRS}{\paperheight-\FOscratchMT-\FOscratchMB-\FOscratchRB}
+ \fi \ifdim\FOscratchRE>\zeropoint \FOregionbuilder
+ {region-end}{righttop}
+ {\FOscratchMR}{\FOscratchMT+\FOscratchRA}
+ {\FOscratchRE}{\paperheight-\FOscratchMT-\FOscratchMB-\FOscratchRB}
+ \fi
+
+\stopsetups
+
+\startsetups fo:regions:process:false:false
+
+ \directsetup{fo:regions:modes}
+
+ \ifdim\FOscratchRB>\zeropoint \FOregionbuilder
+ {region-before}{lefttop}
+ {\FOscratchML+\FOscratchRS}{\FOscratchMT-\FOscratchEB}
+ {\paperwidth-\FOscratchML-\FOscratchMR-\FOscratchRS-\FOscratchRE}{\FOscratchRB}
+ \fi \ifdim\FOscratchRA>\zeropoint \FOregionbuilder
+ {region-after}{leftbottom}
+ {\FOscratchML+\FOscratchRS}{\FOscratchMB-\FOscratchEA}
+ {\paperwidth-\FOscratchML-\FOscratchMR-\FOscratchRS-\FOscratchRE}{\FOscratchRA}
+ \fi \ifdim\FOscratchRS>\zeropoint \FOregionbuilder
+ {region-start}{lefttop}
+ {\FOscratchML}{\FOscratchMT}
+ {\FOscratchRS}{\paperheight-\FOscratchMT-\FOscratchMB}
+ \fi \ifdim\FOscratchRE>\zeropoint \FOregionbuilder
+ {region-end}{righttop}
+ {\FOscratchMR}{\FOscratchMT}
+ {\FOscratchRE}{\paperheight-\FOscratchMT-\FOscratchMB}
+ \fi
+
+\stopsetups
+
+\startsetups fo:before:each:page
+
+ \writeFOstatus{setting up layout \currentlayout}
+ \directsetup{layout:\currentlayout}
+ \directsetup{fo:regions:process}
+
+\stopsetups
+
+\prependtoks
+ \directsetup{fo:before:each:page}%
+\to \everybeforepagebody
+
+%D Element: fo:title
+
+% \XMLattributeset{fo:aural},
+% color=,
+% line-height=,
+
+\defineXMLignore
+ [fo:title]
+ [\XMLattributeset{fo:inherited},\XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:margin-inline},
+ visibility=]
+
+%D Element: fo:block
+
+\defineXMLenvironment
+ [fo:block]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:hyphenation},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:relative-position},
+ \XMLattributeset{fo:keeps-and-breaks},
+% text-depth=,
+% text-altitude=,
+ span=,
+ visibility=]
+ {\beginXMLelement\directsetup{fo:block:start}}
+ {\directsetup{fo:block:stop}\endXMLelement}
+
+\startsetups fo:block:start
+
+ \endgraf
+
+ \writeFOstatus{fo:block in line \the\inputlineno}
+
+\doif{\XMLpar{fo:block}{span}{}}{all}{\ifinsidecolumns \startcolumnsetspan[fo:set] \fi}
+
+ \begingroup
+
+ \directsetup{fe:setup}
+
+ \directsetup{fo:break-and-space:before}
+
+ \begingroup
+
+ \setFOreference{fo:block}
+
+ \increment\FOblocklevel
+
+ \directsetup{fo:font:setup}
+
+ % \setupinterlinespace % no, interferes with columnset and lineheight
+
+ \directsetup{fo:line-height:setup}
+
+ \directsetup{fo:indent:setup}% hier ?
+
+ \doifsomething{\XMLop{background-color}}
+ {\checkhexcolor[\XMLop{background-color}]
+ \doifcolorelse{\XMLop{background-color}}
+ \donothing
+ {\setXMLpar{fo:block}{background-color}{}}}
+
+ \doifsomething{\XMLop{color}}
+ {\checkhexcolor[\XMLop{color}]
+ \doifcolorelse{\XMLop{color}}
+ \donothing
+ {\setXMLpar{fo:block}{color}{}}}
+
+ \doifsomething{\XMLop{background-color}}
+ {\expanded
+ {\definetextbackground
+ [FOattribute-\FOblocklevel]
+ [location=paragraph,
+ color=\XMLop{color},
+ style=,
+ before=,
+ after=,
+ background=color,
+ backgroundcolor=\XMLop{background-color}]}}
+
+ \endgraf
+
+ \getvalue{startFOattribute-\FOblocklevel}
+
+ \directsetup{fo:hyphenation:setup}
+ \directsetup{fo:align:setup}
+ \directsetup{fo:margin:setup}
+
+ \doif{\XMLop{wrap-option}}{no-wrap}
+ {\obeylines}
+
+ \doif{\XMLop{white-space-collapse}}{false}
+ {\obeyspaces}
+
+ % todo : remember old one and do like fonts
+
+ \directsetup{fo:textindent:setup}
+
+\stopsetups
+
+\startsetups fo:block:stop
+
+ \endstrut \endgraf
+
+ \getvalue{stopFOattribute-\FOblocklevel}
+
+ \endgraf
+
+ \endgroup
+
+ \directsetup{fo:break-and-space:after}
+
+ \endgroup
+
+ \doif{\XMLpar{fo:block}{span}{}}{all}{\ifinsidecolumns \stopcolumnsetspan \fi}
+
+\stopsetups
+
+\startsetups fo:textindent:setup
+
+ \edefXMLinh\xFOtextindent{text-indent}
+
+ \doifsomething\xFOtextindent
+ {\scratchdimen\hsize
+ \setpercentdimen\scratchdimen\xFOtextindent
+ \expanded{\setupindenting[\the\scratchdimen]}}
+
+\stopsetups
+
+\indenting[always] % can be zero points
+
+% todo: map
+
+\mapXMLvalue {fo:break} {column} {\column}
+\mapXMLvalue {fo:break} {page} {\page}
+\mapXMLvalue {fo:break} {even-page} {\page[even]}
+\mapXMLvalue {fo:break} {odd-page} {\page[odd]}
+
+% keep-together : either vbox or something \interlinepenalty\maxdimen ?
+%
+% nasty interference with accumulated skips
+
+\mapXMLvalue {fo:keep-next} {auto} {}
+\mapXMLvalue {fo:keep-next} {always} {\nobreak}
+
+\mapXMLvalue {fo:keep-prev} {auto} {}
+\mapXMLvalue {fo:keep-prev} {always} {\nobreak}
+
+\mapXMLvalue {fo:keep-start} {auto} {}
+\mapXMLvalue {fo:keep-start} {always} {\interlinepenalty\maxdimen}
+
+\mapXMLvalue {fo:keep-stop} {auto} {}
+\mapXMLvalue {fo:keep-stop} {always} {}
+
+\newskip\FOsavedlastskip
+
+\startsetups fo:break-and-space:before
+
+ \XMLval{fo:break}{\XMLop{break-before}}{}
+
+ \FOsavedlastskip \lastskip \ifdim\FOsavedlastskip>\zeropoint \vskip-\FOsavedlastskip \fi
+
+ \XMLval{fo:keep-start}{\XMLop{keep-together}}\empty
+ \XMLval{fo:keep-start}{\XMLop{keep-together.within-column}}\empty
+ \XMLval{fo:keep-start}{\XMLop{keep-together.within-page}}\empty
+
+ \XMLval{fo:keep-prev} {\XMLop{keep-with-previous}}\empty
+ \XMLval{fo:keep-prev} {\XMLop{keep-with-previous.within-column}}\empty
+ \XMLval{fo:keep-prev} {\XMLop{keep-with-previous.within-page}}\empty
+
+ \ifdim\FOsavedlastskip>\zeropoint \vskip\FOsavedlastskip \fi
+
+ \doFObeforeskip\currentXMLelement
+
+\stopsetups
+
+\startsetups fo:break-and-space:after
+
+% \doFOafterskip\currentXMLelement
+
+ \FOsavedlastskip \lastskip \ifdim\FOsavedlastskip>\zeropoint \vskip-\FOsavedlastskip \fi
+
+ \XMLval{fo:keep-stop}{\XMLop{keep-together}}\empty
+ \XMLval{fo:keep-stop}{\XMLop{keep-together.within-column}}\empty
+ \XMLval{fo:keep-stop}{\XMLop{keep-together.within-page}}\empty
+
+ \XMLval{fo:keep-next}{\XMLop{keep-with-next}}\empty
+ \XMLval{fo:keep-next}{\XMLop{keep-with-next.within-column}}\empty
+ \XMLval{fo:keep-next}{\XMLop{keep-with-next.within-page}}\empty
+
+ \ifdim\FOsavedlastskip>\zeropoint \vskip\FOsavedlastskip \fi
+
+ \doFOafterskip\currentXMLelement
+
+ \XMLval{fo:break}{\XMLop{break-after}}{}
+
+\stopsetups
+
+\startsetups fo:space:start
+ \doFOstartspace\currentXMLelement
+\stopsetups
+
+\startsetups fo:space:end
+ \doFOendspace\currentXMLelement
+\stopsetups
+
+\startsetups fo:indent:setup
+
+ \doifsomething{\XMLop{start-indent}}{\advance\leftskip \XMLop{start-indent}\relax}
+ \doifsomething{\XMLop{end-indent}} {\advance\rightskip\XMLop{end-indent} \relax}
+
+% \FOattributeT
+% \FOattributeR
+% \FOattributeB
+% \FOattributeL
+
+
+\stopsetups
+
+\mapXMLvalue {fo:align} {center} {\raggedcenter}
+\mapXMLvalue {fo:align} {left} {\raggedright}
+\mapXMLvalue {fo:align} {right} {\raggedleft}
+\mapXMLvalue {fo:align} {begin} {\raggedright}
+\mapXMLvalue {fo:align} {start} {\raggedright}
+\mapXMLvalue {fo:align} {end} {\raggedleft}
+
+\mapXMLvalue {fo:align-key} {center} {middle}
+\mapXMLvalue {fo:align-key} {left} {flushleft}
+\mapXMLvalue {fo:align-key} {right} {flushright}
+\mapXMLvalue {fo:align-key} {begin} {flushleft}
+\mapXMLvalue {fo:align-key} {start} {flushleft}
+\mapXMLvalue {fo:align-key} {end} {flushright}
+
+\startsetups fo:align:setup
+
+ \XMLval{fo:align}{\XMLop{text-align}}{}
+
+\stopsetups
+
+\startsetups fo:margin:setup
+
+ \checkFOmargin{fo:block}
+
+ \FOscratchML \XMLpar{fo:block}{margin-left} \zeropoint
+ \FOscratchMR \XMLpar{fo:block}{margin-right} \zeropoint
+ \FOscratchMT \XMLpar{fo:block}{margin-top} \zeropoint
+ \FOscratchMB \XMLpar{fo:block}{margin-bottom}\zeropoint
+
+ \advance\leftskip \FOscratchML
+ \advance\rightskip\FOscratchMR
+
+\stopsetups
+
+% todo: font-stretch
+%
+% ultra-condensed
+% extra-condensed
+% condensed
+% semi-condensed
+% expanded
+% extra-expanded
+% ultra-expanded
+%
+% wider narrower
+
+\mapXMLvalue {fo:font-size} {xx-small} {\dFOfontsize0.58\dFOfontsize}
+\mapXMLvalue {fo:font-size} {x-small} {\dFOfontsize0.69\dFOfontsize}
+\mapXMLvalue {fo:font-size} {small} {\dFOfontsize0.83\dFOfontsize}
+\mapXMLvalue {fo:font-size} {medium} {\relax}
+\mapXMLvalue {fo:font-size} {large} {\dFOfontsize1.20\dFOfontsize}
+\mapXMLvalue {fo:font-size} {x-large} {\dFOfontsize1.44\dFOfontsize}
+\mapXMLvalue {fo:font-size} {xx-large} {\dFOfontsize1.73\dFOfontsize}
+
+\mapXMLvalue {fo:font-size} {smaller} {\dFOfontsize0.83\dFOfontsize}
+\mapXMLvalue {fo:font-size} {larger} {\dFOfontsize1.20\dFOfontsize}
+
+\newdimen\dFOfontsize
+
+% evt class Times Helvetica
+
+\definefontsynonym [FO:Times] [Times-Roman]
+\definefontsynonym [FO:Times:bold] [Times-Bold]
+\definefontsynonym [FO:Times:italic] [Times-Italic]
+\definefontsynonym [FO:Times:bold:italic] [Times-BoldItalic]
+
+\definefontsynonym [FO:Times:small-caps] [Times-Roman]
+\definefontsynonym [FO:Times:bold:small-caps] [Times-Bold]
+\definefontsynonym [FO:Times:italic:small-caps] [Times-Italic]
+\definefontsynonym [FO:Times:bold:italic:small-caps] [Times-BoldItalic]
+
+\definefontsynonym [FO:Helvetica] [Helvetica]
+\definefontsynonym [FO:Helvetica:bold] [Helvetica-Bold]
+\definefontsynonym [FO:Helvetica:italic] [Helvetica-Italic]
+\definefontsynonym [FO:Helvetica:bold:italic] [Helvetica-BoldItalic]
+
+\definefontsynonym [FO:Helvetica:small-caps] [Helvetica]
+\definefontsynonym [FO:Helvetica:bold:small-caps] [Helvetica-Bold]
+\definefontsynonym [FO:Helvetica:italic:small-caps] [Helvetica-Italic]
+\definefontsynonym [FO:Helvetica:bold:italic:small-caps] [Helvetica-BoldItalic]
+
+\definefontsynonym [FO:Courier] [Courier]
+\definefontsynonym [FO:Courier:bold] [Courier-Bold]
+\definefontsynonym [FO:Courier:italic] [Courier-Oblique]
+\definefontsynonym [FO:Courier:bold:italic] [Courier-BoldOblique]
+
+\definefontsynonym [FO:Courier:small-caps] [Courier]
+\definefontsynonym [FO:Courier:bold:small-caps] [Courier-Bold]
+\definefontsynonym [FO:Courier:italic:small-caps] [Courier-Oblique]
+\definefontsynonym [FO:Courier:bold:italic:small-caps] [Courier-BoldOblique]
+
+\definefontsynonym [FO:Symbol] [ZapfDingbats]
+
+\definefontsynonym [FO:Computer-Modern-Typewriter] [ComputerModernMono]
+\definefontsynonym [FO:Computer-Modern-Typewriter:italic] [ComputerModernMono-Slanted]
+
+\definefontsynonym [*Times Roman*] [Times]
+
+% nasty: no FO prefix
+
+\definefontsynonym [*serif*] [Times]
+\definefontsynonym [*sans-serif*] [Helvetica]
+\definefontsynonym [*monospace*] [Courier]
+
+\definefontsynonym [*cursive*] [Times]
+\definefontsynonym [*fantasy*] [Helvetica]
+
+\definefontsynonym [*Arial*] [Helvetica]
+\definefontsynonym [*Times Roman*] [Times]
+\definefontsynonym [*Wingdings*] [ZapfDingbats]
+
+% \definefontsynonym [Computer-Modern-Typewriter] [ComputerModernMono]
+% \definefontsynonym [monospace] [ComputerModernMono]
+
+\startsetups fo:fonts:reset
+
+ \dFOfontsize=\bodyfontsize
+
+ \def\FOfontsize {10pt}% {12pt}
+ \def\FOfontfamily {Times}
+ \def\FOfontweight {normal}
+ \def\FOfontstyle {normal}
+ \def\FOfontvariant {normal}
+ \def\FOfontsizeadjust{1}
+
+ \def\FOtextdepth {}
+ \def\FOtextaltitude {}
+ \def\FOlineheight {}
+
+ \def\FOfontdefinition{}
+ \def\FOfontname {}
+
+\stopsetups
+
+\def\FOfontdefinition{}
+\def\FOfontname {}
+
+\directsetup{fo:fonts:reset}
+
+% test for \FOfontvariant: normal or else
+
+\def\setFOfontname
+ {\edef\xFOfontname{FO:\FOfontfamily:\FOfontweight:\FOfontstyle:\FOfontvariant}%
+ %\begingroup\infofont\xFOfontname]\endgroup
+ \doifelsefontsynonym\xFOfontname
+ {\let\FOfontname\xFOfontname}
+ {\edef\xFOfontname{FO:\FOfontfamily:\FOfontweight:\FOfontstyle}%
+ \doifelsefontsynonym\xFOfontname
+ {\let\FOfontname\xFOfontname}
+ {\edef\xFOfontname{FO:\FOfontfamily:\FOfontstyle}%
+ \doifelsefontsynonym\xFOfontname
+ {\let\FOfontname\xFOfontname}
+ {\edef\xFOfontname{FO:\FOfontfamily:\FOfontweight}%
+ \doifelsefontsynonym\xFOfontname
+ {\let\FOfontname\xFOfontname}
+ {\edef\xFOfontname{FO:\FOfontfamily}%
+ \doifelsefontsynonym\xFOfontname
+ {\let\FOfontname\xFOfontname}
+ {}}}}}}
+
+% \unprotected \def\doifelseFOfontsynonym#1#2#3#4#5% family weight style variant default
+% {\edef\FOfontname
+% {\ifcsname \??ff\fontclass FO:#1:#2:#3:#4\endcsname FO:#1:#2:#3:#4%
+% \else\ifcsname\??ff\fontclass FO:#1:#2:#3\endcsname FO:#1:#2:#3%
+% \else\ifcsname\??ff\fontclass FO:#1:#3\endcsname FO:#1:#3%
+% \else\ifcsname\??ff\fontclass FO:#1:#2\endcsname FO:#1:#2%
+% \else\ifcsname\??ff\fontclass FO:#1\endcsname FO:#1%
+% \else #5%
+% \fi\fi\fi\fi\fi}}
+
+\startsetups fo:font:family:check
+
+ \doifelsefontsynonym{*\FOfontfamily*}
+ {\expandfontsynonym\FOfontfamily{*\FOfontfamily*}}
+ {}
+
+\stopsetups
+
+\let\FOfont\empty
+
+\startsetups fo:font:setup
+
+ % todo: optimize, define fonts first time and do that global
+
+ \edefXMLinh\xFOfont {font}
+ \edefXMLinh\xFOfontsize {font-size}
+ \edefXMLinh\xFOfontsizeadjust{font-size-adjust}
+ \edefXMLinh\xFOfontfamily {font-family}
+ \edefXMLinh\xFOfontweight {font-weight}
+ \edefXMLinh\xFOfontstyle {font-style}
+ \edefXMLinh\xFOfontvariant {font-variant}
+
+% \edef\xFOfont {\XMLpar{fo}{font}{}}
+% \edef\xFOfontsize {\XMLpar{fo}{font-size}{}}
+% \edef\xFOfontsizeadjust{\XMLpar{fo}{font-size-adjust}{}}
+% \edef\xFOfontfamily {\XMLpar{fo}{font-family}{}}
+% \edef\xFOfontweight {\XMLpar{fo}{font-weight}{}}
+% \edef\xFOfontstyle {\XMLpar{fo}{font-style}{}}
+% \edef\xFOfontvariant {\XMLpar{fo}{font-variant}{}}
+
+ \donefalse
+
+ \ifx\xFOfont\empty \else \ifx\xFOfont\relax \else
+ \let\FOfont\xFOfont
+ \checkFOfont\FOfont
+ \fi \fi
+
+ \ifx\xFOfontsize\empty \else \ifx\xFOfontsize\FOfontsize \else
+ \let\FOfontsize\xFOfontsize
+ \doifXMLvalelse{fo:font-size}\FOfontsize
+ {\XMLval{fo:font-size}\FOfontsize\empty}
+ {\setpercentdimen\dFOfontsize\FOfontsize}
+ \fi \fi
+
+ \ifx\xFOfontsizeadjust\empty \else
+ \doifelse\xFOfontsizeadjust{none}
+ {\def\FOfontsizeadjust{1}}
+ {\let\FOfontsizeadjust\xFOfontsizeadjust}
+ \fi
+
+ \ifx\xFOfontfamily\empty \else \ifx\xFOfontfamily\FOfontfamily \else
+ \donetrue \let\FOfontfamily\xFOfontfamily \directsetup{fo:font:family:check}
+ \fi \fi
+ \ifx\xFOfontweight\empty \else \ifx\xFOfontweight\FOfontweight \else
+ \donetrue \let\FOfontweight\xFOfontweight
+ \fi \fi
+ \ifx\xFOfontstyle\empty \else \ifx\xFOfontstyle\FOfontstyle \else
+ \donetrue \let\FOfontstyle\xFOfontstyle
+ \fi \fi
+ \ifx\xFOfontvariant\empty \else \ifx\xFOfontvariant\FOfontvariant \else
+ \donetrue \let\FOfontvariant\xFOfontvariant
+ \fi \fi
+
+ \ifdone
+ \setFOfontname
+ \ifx\FOfontname\empty % klopt dit
+ \edef\xFOfontdefinition{\purefontname{\font} at \the\dimexpr(\FOfontsizeadjust\dFOfontsize)}
+% \let\xFOfontdefinition\empty
+ \else
+ \edef\xFOfontdefinition{\FOfontname\space at \the\dimexpr(\FOfontsizeadjust\dFOfontsize)}
+ \fi
+ \else
+ \edef\xFOfontdefinition{\purefontname{\font} at \the\dimexpr(\FOfontsizeadjust\dFOfontsize)}
+ \fi
+
+ \ifx\xFOfontdefinition\empty \else
+ \ifx\FOfontdefinition\xFOfontdefinition
+ \else
+ \let\FOfontdefinition\xFOfontdefinition
+ \expanded{\definedfont[\FOfontdefinition]}
+ \fi
+ \fi
+
+\stopsetups
+
+\newdimen\dFOlineheight
+\newdimen\dFOdepth
+\newdimen\dFOaltitude
+
+\let\FOlineheight \empty
+\let\FOtextdepth \empty
+\let\FOtextaltitude\empty
+
+\startsetups fo:line-height:setup
+
+ \edefXMLinh\xFOtextdepth {text-depth}
+ \edefXMLinh\xFOtextaltitude{text-altitude}
+ \edefXMLinh\xFOlineheight {line-height}
+
+% \edef\xFOtextdepth {\XMLpar{fo}{text-depth}{}}
+% \edef\xFOtextaltitude{\XMLpar{fo}{text-altitude}{}}
+% \edef\xFOlineheight {\XMLpar{fo}{line-height}{}}
+
+ \ifx\xFOtextdepth\empty \else \ifx\xFOtextdepth\FOtextdepth \else
+ \let\FOtextdepth\xFOtextdepth
+ \doifnot\FOtextdepth{use-font-metrics}
+ {\setstrut \dFOdepth\strutdepth
+ \setpercentdimen\dFOdepth\FOtextdepth
+ \setupinterlinespace[mindepth=\dFOdepth]}
+ \fi \fi
+
+ \ifx\xFOtextaltitude\empty \else \ifx\xFOtextaltitude\FOtextaltitude \else
+ \let\FOtextaltitude\xFOtextaltitude
+ \doifnot\FOtextaltitude{use-font-metrics}
+ {\setstrut \dFOaltitude\strutheight \advance\dFOaltitude\strutdepth
+ \setpercentdimen\dFOaltitude\FOtextaltitude
+ \setupinterlinespace[minheight=\dFOaltitude]}
+ \fi \fi
+
+\ifinsidecolumns \else
+
+ \ifx\xFOlineheight\empty \else \ifx\xFOlineheight\FOlineheight \else
+ \let\FOlineheight\xFOlineheight
+ \doifelse\FOlineheight{normal}
+ {\dFOlineheight2.8ex
+ \setupinterlinespace[line=\dFOlineheight]}
+ {\doifnot\FOlineheight{use-font-metrics}
+ {\setstrut \dFOlineheight\strutheight \advance\dFOlineheight\strutdepth
+ \setpercentdimen\dFOlineheight\FOlineheight
+ \setupinterlinespace[line=\dFOlineheight]}}
+ \fi \fi
+
+\fi
+
+\stopsetups
+
+\let\orphanpenalty \clubpenalty
+\let\orphanpenalties\clubpenalties
+
+\newcount\FOwidows \FOwidows =2
+\newcount\FOorphans \FOorphans=2
+
+\mapXMLvalue {fo:hyphens} {false} {\nohyphens}
+\mapXMLvalue {fo:hyphens} {true} {\dohyphens}
+
+\startsetups fo:hyphenation:setup
+
+ \edefXMLinh\xFOhyphenate {hyphenate}
+ \edefXMLinh\xFOwidows {widows}
+ \edefXMLinh\xFOorphans {orphans}
+
+% \edef\xFOhyphenate {\XMLpar{fo}{hyphenate}{}}
+% \edef\xFOwidows {\XMLpar{fo}{widows}{}}
+% \edef\xFOorphans {\XMLpar{fo}{orphans}{}}
+
+ \ifx\xFOhyphenate\empty \else
+ \XMLval{fo:hyphens}{\xFOhyphenate}\empty
+ \fi
+ \ifx\xFOwidows\empty \else \ifnum\xFOwidows=\FOwidows \else
+ \FOwidows\xFOwidows \setpenalties\widowpenalties\FOwidows\maxdimen
+ \fi \fi
+ \ifx\xFOorphans\empty \else \ifnum\xFOorphans=\FOorphans \else
+ \FOorphans\xFOorphans \setpenalties\clubpenalties\FOorphans\maxdimen
+ \fi \fi
+
+ % hyphenation-character
+
+\stopsetups
+
+%D fo:block-container
+
+% todo: potential optimization: set fonts and spacing at container level
+
+% display-align=,
+% intrusion-displace=,
+% reference-orientation=,
+% writing-mode=,
+
+\defineXMLenvironment
+ [fo:block-container]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:absolute-positioning},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:keeps-and-breaks},
+ block-progression-dimension=,
+ inline-progression-dimension=,
+ clip=,
+ height=,
+ overflow=,
+ span=,
+ width=,
+ z-index=]
+ {\beginXMLelement\directsetup{fo:block-container:start}}
+ {\directsetup{fo:block-container:stop}\endXMLelement}
+
+\mapXMLvalue {fo:block-container:start} {absolute} {\directsetup{fo:block-container:start:pos}}
+\mapXMLvalue {fo:block-container:start} {fixed} {\directsetup{fo:block-container:start:pos}}
+
+\mapXMLvalue {fo:block-container:stop} {absolute} {\directsetup{fo:block-container:stop:pos}}
+\mapXMLvalue {fo:block-container:stop} {fixed} {\directsetup{fo:block-container:stop:pos}}
+
+\startsetups fo:block-container:start
+
+ \XMLval{fo:block-container:start}{\XMLpar{fo:block-container}{absolute-position}{}}{}
+
+ \setFOreference{fo:block-container}
+
+\stopsetups
+
+\startsetups fo:block-container:stop
+
+ \XMLval{fo:block-container:stop}{\XMLpar{fo:block-container}{absolute-position}{}}{}
+
+\stopsetups
+
+% i need to figure out the details (specs are a bit fuzzy)
+
+% replaced, see position
+
+\newdimen\FOcontainerW \newdimen\FOcontainerX \newdimen\FOcontainerL \newdimen\FOcontainerR \newdimen\FOcontainerWW
+\newdimen\FOcontainerH \newdimen\FOcontainerY \newdimen\FOcontainerT \newdimen\FOcontainerB \newdimen\FOcontainerHH
+
+\startsetups fo:block-container:start:pos
+
+ % todo: textwidth -> region dimensions
+
+ \begingroup % \forgetall
+
+ \FOcontainerWW\textwidth
+ \FOcontainerHH\textheight
+ \def\FOlayername{\XMLpar{fo:flow}{flow-name}{xsl-region-body}}
+
+ \iftracingFO \tracelayerstrue \fi
+
+ \directsetup{fo:preset:layer}
+
+ \setlayerframed
+ [\XMLpar{fo:flow}{flow-name}{xsl-region-body}]
+ [frame=off,
+ width=\FOcontainerW,
+ height=\FOcontainerH]
+
+ \bgroup
+
+\stopsetups
+
+\startsetups fo:block-container:stop:pos
+
+ \egroup
+
+ \endgroup
+
+\stopsetups
+
+%D fo:bidi-override
+
+% \XMLattributeset{aural},
+% color=,
+% direction=,
+% letter-spacing=,
+% line-height=,
+% word-spacing=,
+
+\defineXMLenvironment
+ [fo:bidi-override]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:relative-position},
+ score-spaces=,
+ unicode-bidi=]
+ {\beginXMLelement}
+ {\endXMLelement}
+
+% todo
+
+%D fo:character
+
+% \XMLattributeset{fo:aural},
+% color=,
+% glyph-orientation-horizontal=,
+% glyph-orientation-vertical=,
+% line-height=,
+
+\defineXMLsingular
+ [fo:character]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:hyphenation},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ \XMLattributeset{fo:character},
+ alignment-adjust=,
+ baseline-shift=,
+ dominant-baseline=,
+% text-depth=,
+% text-altitude=,
+ keep-with-next=,
+ keep-with-previous=,
+ score-spaces=,
+ visibility=]
+ {\directsetup{fo:character:process}}
+
+\mapXMLvalue {fo:vertical-align} {baseline} {\hbox}
+\mapXMLvalue {fo:vertical-align} {sub} {\low}
+\mapXMLvalue {fo:vertical-align} {super} {\high}
+\mapXMLvalue {fo:vertical-align} {inherit} {\firstofoneargument}
+
+\startsetups fo:character:process
+
+ % border
+ % font
+ % margin
+ % positioning
+ % baseline
+ % color
+ % depth and altitude
+ % keep-with
+ % lineheight
+
+ \dontleavehmode \begingroup
+
+ \directsetup{fe:setup}
+ \directsetup{fo:font:setup}
+
+ \iftracingFO \ruledhbox \else \hbox \fi \bgroup
+
+ \doifsomethingXMLop{vertical-align}
+ {\doifXMLvalelse{fo:vertical-align}{\XMLop{vertical-align}}
+ {\XMLval{fo:vertical-align}{\XMLop{vertical-align}}{}}
+ {\wordshiftamount\lineheight
+ \setpercentdimen\wordshiftamount{\XMLop{vertical-align}}
+ \shiftedword}}
+
+ {\directsetup{fo:character:orient}}
+
+ \egroup \endgroup
+
+\stopsetups
+
+\startsetups fo:character:orient
+
+% \rotate[rotation=-\XMLop{glyph-orientation-horizontal}]
+
+ \doifsomethingXMLop{glyph-orientation-horizontal}
+ {\rotate[rotation=\XMLval{fo:reference-orientation}{\XMLop{glyph-orientation-horizontal}}{0}]}
+ {\XMLop{character}}
+
+\stopsetups
+
+%D fo:initial-property-set
+
+% \XMLattributeset{fo:aural},
+% color=,
+% letter-spacing=,
+% line-height=,
+% text-transform=,
+% word-spacing=,
+
+\defineXMLprocess
+ [fo:initial-property-set]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:relative-position},
+ score-spaces=,
+ text-decoration=,
+ text-shadow=]
+
+%D fo:external-graphic
+
+\useMPlibrary[dum]
+
+% \XMLattributeset{fo:aural},
+% display-align=,
+% height=,
+% text-align=,
+
+\defineXMLenvironmentsave
+ [fo:external-graphic]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ block-progression-dimension=,
+ clip=,
+ content-height=,
+ content-type=,
+ content-width=,
+ dominant-baseline=,
+ height=,
+ inline-progression-dimension=,
+ keep-with-next=,
+ keep-with-previous=,
+ overflow=,
+ scaling=,
+ scaling-method=,
+ src=dummy,
+ width=]
+ {}
+ {\directsetup{fo:external-graphic:process}}
+
+\newdimen\FOgraphicwidth
+\newdimen\FOgraphicheight
+
+\mapXMLvalue {external-graphic:align} {top} {\tbox}
+\mapXMLvalue {external-graphic:align} {bottom} {\bbox}
+\mapXMLvalue {external-graphic:align} {center} {\cbox}
+
+\startsetups fo:external-graphic:process
+
+ \doifelsenothing{\XMLop{content-height}}
+ {\FOgraphicheight\zeropoint}
+ {\doifelse{\XMLop{content-height}}{scale-to-fit}% is this official ?
+ {\FOgraphicwidth\zeropoint}
+ {\doifelse{\XMLop{content-height}}{auto}
+ {\FOgraphicheight\zeropoint}
+ {\FOgraphicheight\lineheight
+ \setpercentdimen\FOgraphicheight{\XMLop{content-height}}}}}
+
+ \doifelsenothing{\XMLop{content-width}}
+ {\FOgraphicwidth\zeropoint}
+ {\doifelse{\XMLop{content-width}}{scale-to-fit}% is this official ?
+ {\FOgraphicwidth\zeropoint}
+ {\doifelse{\XMLop{content-width}}{auto}
+ {\FOgraphicwidth\zeropoint}
+ {\FOgraphicwidth1em
+ \setpercentdimen\FOgraphicwidth {\XMLop{content-width}}}}}
+
+ % leeg maken vars gaat ook goed, dan een \externalfigure
+
+ % todo : height/width scale-to-fit: factor=...
+
+ \setbox\scratchbox\hbox
+ {\setFOimagename{\XMLpar{fo:external-graphic}{src}{dummy}}
+ \ifdim\FOgraphicheight>\zeropoint
+ \ifdim\FOgraphicwidth>\zeropoint
+ \externalfigure[\FOimagename][height=\FOgraphicheight,width=\FOgraphicwidth]
+ \else
+ \externalfigure[\FOimagename][height=\FOgraphicheight]
+ \fi
+ \else
+ \ifdim\FOgraphicwidth>\zeropoint
+ \externalfigure[\FOimagename][width=\FOgraphicwidth]
+ \else
+ \externalfigure[\FOimagename]
+ \fi
+ \fi}
+
+ \dontleavehmode \XMLval{external-graphic:align}{\XMLop{vertical-align}}{}{\box\scratchbox}
+
+\stopsetups
+
+%D fo:instream-foreign-object
+
+% like external-graphic, only no src
+
+% \XMLattributeset{fo:aural},
+% display-align=,
+% line-height=,
+% text-align=,
+
+\defineXMLprocess
+ [fo:instream-foreign-object]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ block-progression-dimension=,
+ clip=,
+ content-height=,
+ content-type=,
+ content-width=,
+ dominant-baseline=,
+ height=,
+ inline-progression-dimension=,
+ keep-with-next=,
+ keep-with-previous=,
+ overflow=,
+ scaling=,
+ scaling-method=,
+ width=]
+
+%D Element: fo:inline
+
+% \XMLattributeset{fo:aural},
+% line-height=,
+% wrap-option=,
+% color=,
+% keep-together=,
+
+\defineXMLnestedenvironmentsave
+ [fo:inline]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ block-progression-dimension=,
+ dominant-baseline=,
+ height=,
+ inline-progression-dimension=,
+ keep-with-next=,
+ keep-with-previous=,
+ text-decoration=,
+ visibility=,
+ width=]
+ {\beginXMLelement}
+ {\directsetup{fo:inline:process}\endXMLelement}
+
+\defineXMLsingular
+ [fo:inline]
+ {}
+
+% baseline-shift: baseline sub super % dimen inherit
+
+\chardef\isolatedwordsmode=1
+
+\newdimen\wordshiftamount
+
+\def\shiftedword{\raise\wordshiftamount\hbox}
+
+\long\def\shiftedwords#1{\processisolatedwords{#1}\shiftedword}
+\long\def\normalwords #1{\processisolatedwords{#1}\hbox}
+\long\def\highwords #1{\processisolatedwords{#1}\high}
+\long\def\lowwords #1{\processisolatedwords{#1}\low}
+
+\mapXMLvalue {fo:baseline-shift} {baseline} {\normalwords}
+\mapXMLvalue {fo:baseline-shift} {sub} {\lowwords}
+\mapXMLvalue {fo:baseline-shift} {super} {\highwords}
+\mapXMLvalue {fo:baseline-shift} {inherit} {\firstofoneargument}
+
+\startsetups fo:inline:process
+
+ \directsetup{fo:position:start}
+
+ \dontleavehmode
+
+ \doFOreference{fo:inline}
+
+ \begingroup
+
+ \directsetup{fe:setup}
+ \directsetup{fo:space:start}
+
+ \begingroup
+
+ \directsetup{fo:hyphenation:setup}
+ \directsetup{fo:font:setup}
+
+ \doifelsenothing{\XMLop{baseline-shift}}
+ {\XMLflushself}
+ {\doifXMLvalelse{fo:baseline-shift}{\XMLop{baseline-shift}}
+ {\XMLval{fo:baseline-shift}{\XMLop{baseline-shift}}{}{\XMLflushself}}
+ {\wordshiftamount\lineheight
+ \setpercentdimen\wordshiftamount{\XMLop{baseline-shift}}
+ \shiftedwords{\XMLflushself}}}
+
+ \endgroup
+
+ \directsetup{fo:space:end}
+
+ \endgroup
+
+ \directsetup{fo:position:stop}
+
+\stopsetups
+
+\startsetups fo:position:start
+ \begingroup
+ \directsetup{fo:position:\XMLop{position}:start}
+ \begingroup
+\stopsetups
+
+\startsetups fo:position:stop
+ \endgroup
+ \directsetup{fo:position:\XMLop{position}:stop}
+ \endgroup
+\stopsetups
+
+\startsetups fo:position:static:start
+\stopsetups
+
+\startsetups fo:position:static:stop
+\stopsetups
+
+\startsetups fo:position:fixed:start
+ \FOcontainerWW\paperwidth
+ \FOcontainerHH\paperheight
+ \def\FOlayername{regions}
+ \directsetup{fo:preset:layer}
+ \setlayer[regions]{\vbox \bgroup \setlocalhsize}
+\stopsetups
+
+\startsetups fo:position:fixed:stop
+ \egroup
+\stopsetups
+
+\enableparpositions % slows down but who uses fo anyway ...
+
+\startsetups fo:position:absolute:start
+ \setbox\FOpositionbox\hbox\bgroup
+\stopsetups
+
+\startsetups fo:position:absolute:stop
+ \egroup
+ % evt uitstellen tot otr, zodat text/realfolio is solved
+ \edef\FOpartag{p:\number\parposcounter}
+ \edef\FOtxttag{text:\realfolio}
+ \FOcontainerWW\MPplus\FOpartag{1}{0pt}
+ \FOcontainerHH\zeropoint % todo: add anchors to each 'object'
+ \directsetup{fo:preset:position}
+ \setlayer
+ [xsl-region-body]
+ [preset=lefttop,
+ hoffset=\dimexpr(\MPx\FOtxttag-\MPx\FOpartag),
+ voffset=\dimexpr(\MPy\FOtxttag+\MPh\FOtxttag-\MPy\FOpartag-\MPh\FOpartag)]
+ {\iftracingFO \ruledhbox \bgroup \fi
+ \offset
+ [method=fixed,
+ leftoffset=\FOcontainerL,
+ rightoffset=\FOcontainerR,
+ topoffset=\FOcontainerT,
+ bottomoffset=\FOcontainerB]
+ {\box\FOpositionbox}
+ \iftracingFO \egroup \fi}
+\stopsetups
+
+\newbox\FOpositionbox
+
+\startsetups fo:position:relative:start
+ \setbox\FOpositionbox\hbox\bgroup
+\stopsetups
+
+\startsetups fo:position:relative:stop
+ \egroup
+ \FOcontainerWW\wd\FOpositionbox
+ \FOcontainerHH\dimexpr(\ht\FOpositionbox+\dp\FOpositionbox)
+ \directsetup{fo:preset:position}
+ \iftracingFO \ruledhbox \bgroup \fi
+ \offset
+ [method=fixed,
+ leftoffset=\FOcontainerL,
+ rightoffset=\FOcontainerR,
+ topoffset=\FOcontainerT,
+ bottomoffset=\FOcontainerB]
+ {\box\FOpositionbox}
+ \iftracingFO \egroup \fi
+\stopsetups
+
+%
+
+\startsetups fo:preset:position
+
+ \FOcontainerW\zeropoint \FOcontainerL\zeropoint \FOcontainerR\zeropoint
+ \FOcontainerH\zeropoint \FOcontainerT\zeropoint \FOcontainerB\zeropoint
+
+ \doifnot{\XMLop{left}} {auto}{\FOcontainerL\FOcontainerWW\setpercentdimen\FOcontainerL{\XMLop{left}}}
+ \doifnot{\XMLop{right}} {auto}{\FOcontainerR\FOcontainerWW\setpercentdimen\FOcontainerR{\XMLop{right}}}
+ \doifnot{\XMLop{top}} {auto}{\FOcontainerT\FOcontainerHH\setpercentdimen\FOcontainerT{\XMLop{top}}}
+ \doifnot{\XMLop{bottom}}{auto}{\FOcontainerB\FOcontainerHH\setpercentdimen\FOcontainerB{\XMLop{bottom}}}
+
+ \doifnot{\XMLop{width}} {auto}{\FOcontainerW\FOcontainerWW\setpercentdimen\FOcontainerW{\XMLop{width}}}
+ \doifnot{\XMLop{height}}{auto}{\FOcontainerH\FOcontainerHH\setpercentdimen\FOcontainerH{\XMLop{height}}}
+
+\stopsetups
+
+\startsetups fo:preset:layer
+
+ \directsetup{fo:preset:position}
+
+ \setuplayer
+ [\FOlayername]
+ [width=\FOcontainerWW,
+ height=\FOcontainerHH]
+
+ \ifzeropt\FOcontainerW
+ \FOcontainerW\dimexpr(\FOcontainerWW-\FOcontainerL-\FOcontainerR)
+ \fi
+ \ifzeropt\FOcontainerH
+ \FOcontainerH\dimexpr(\FOcontainerHH-\FOcontainerT-\FOcontainerB)
+ \fi
+
+ \ifzeropt\FOcontainerB
+ \ifzeropt\FOcontainerL
+ \setuplayer[\FOlayername][preset=righttop, x=\FOcontainerR,y=\FOcontainerT]
+ \else
+ \setuplayer[\FOlayername][preset=lefttop, x=\FOcontainerL,y=\FOcontainerT]
+ \fi
+ \else
+ \ifzeropt\FOcontainerL
+ \setuplayer[\FOlayername][preset=rightbottom,x=\FOcontainerR,y=\FOcontainerB]
+ \else
+ \setuplayer[\FOlayername][preset=leftbottom, x=\FOcontainerL,y=\FOcontainerB]
+ \fi
+ \fi
+
+\stopsetups
+
+%D Element: fo:inline-container
+
+% display-align=,
+% line-height=,
+% reference-orientation=,
+% writing-mode=,
+% keep-together=,
+
+\defineXMLenvironment
+ [fo:inline-container]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ block-progression-dimension=,
+ clip=,
+ dominant-baseline=,
+ height=,
+ inline-progression-dimension=,
+ keep-with-next=,
+ keep-with-previous=,
+ overflow=,
+ width=]
+ {\beginXMLelement\begingroup}
+ {\endgroup\endXMLelement}
+
+%D Element: fo:leader
+
+% also a kind of fake fill
+
+% \XMLattributeset{fo:aural},
+% color=,
+% line-height=,
+% word-spacing=,
+
+\defineXMLenvironmentsave
+ [fo:leader]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ \XMLattributeset{fo:leader-and-rule},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ dominant-baseline=,
+ % text-depth=,
+ % text-altitude=,
+ keep-with-next=,
+ keep-with-previous=,
+ letter-spacing=,
+ text-shadow=,
+ visibility=]
+ {\beginXMLelement}
+ {\directsetup{fo:leader:process}\endXMLelement}
+
+\mapXMLvalue {fo:leader-pattern} {space} {\hfill}
+\mapXMLvalue {fo:leader-pattern} {dots} {.}
+\mapXMLvalue {fo:leader-pattern} {rule} {\hrulefill}
+\mapXMLvalue {fo:leader-pattern} {use-content} {\XMLflushself}
+
+% todo: speed up
+
+\startsetups fo:leader:process
+
+ %tracebackXMLattribute{leader-pattern-width}
+
+ \strut \leaders
+ %edefXMLinh \FOlepatwd {leader-pattern-width}
+ \hbox to \XMLinh{leader-pattern-width}
+ {\hss\XMLval{fo:leader-pattern}{\XMLinh{leader-pattern}}{\hfill}\hss}
+ \hfill \strut
+
+\stopsetups
+
+%D Element: fo:pagenumber
+
+% \XMLattributeset{fo:aural},
+% line-height=,
+% wrap-option=,
+% letter-spacing=,
+% text-transform=,
+% word-spacing=,
+
+\defineXMLsingular
+ [fo:page-number]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ dominant-baseline=,
+ keep-with-next=,
+ keep-with-previous=,
+ score-spaces=,
+% text-altitude=,
+ text-decoration=,
+% text-depth=,
+ text-shadow=,
+ visibility=]
+ {\directsetup{fo:page-number:process}}
+
+\newcount\FOpnrefcounter
+
+\startsetups fo:page-number:process
+
+ \doifelsenothing{\XMLpar{fo:page-sequence}{format}{}}
+ {\pagenumber}
+ {\ifinotr
+ \globallet\FOpnrefnumber\folio
+ \else
+ \global\advance\FOpnrefcounter\plusone
+ \pagereference[pnref:\the\FOpnrefcounter]
+ \doifreferencefoundelse{pnref:\the\FOpnrefcounter}
+ {\globallet\FOpnrefnumber\currentfolioreference}
+ {\globallet\FOpnrefnumber\folio}
+ \fi
+ \expanded{\handletokens\XMLpar{fo:page-sequence}{format}{}}\with{\handleFOformat{\FOpnrefnumber}}}
+
+\stopsetups
+
+\defineconversion[1][\numbers]
+
+\long\def\handleFOformat#1#2%
+ {\defconvertedargument\ascii{#2}%
+ \doifconversiondefinedelse\ascii{\convertnumber\ascii{#1}}{#2}}
+
+%D Element: fo:pagenumber-citation
+
+% same as page-number
+
+% \XMLattributeset{fo:aural},
+% line-height=,
+% wrap-option=,
+% letter-spacing=,
+% text-transform=,
+% word-spacing=,
+
+\defineXMLsingular
+ [fo:page-number-citation]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ ref-id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:font},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ dominant-baseline=,
+ keep-with-next=,
+ keep-with-previous=,
+ score-spaces=,
+% text-altitude=,
+ text-decoration=,
+% text-depth=,
+ text-shadow=,
+ visibility=]
+ {\directsetup{fo:page-number-citation:process}}
+
+\startsetups fo:page-number-citation:process
+
+ \doifreferencefoundelse{\XMLop{ref-id}}
+ {\globallet\FOpnrefnumber\currentfolioreference
+ \globallet\FOpnrefformat\currenttextreference}
+ {\gdef\FOpnrefnumber{?}
+ \gdef\FOpnrefformat{}}
+
+ \doifelsenothing{\FOpnrefformat}
+ {\FOpnrefnumber}
+ {\expanded{\handletokens\FOpnrefformat}\with{\handleFOformat{\FOpnrefnumber}}}
+
+\stopsetups
+
+%D Element: fo:table-and-caption
+
+% \XMLattributeset{fo:aural},
+% text-align=,
+% caption-side=,
+% intrusion-displace=,
+% keep-together=,
+
+\defineXMLenvironment
+ [fo:table-and-caption]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:relative-position},
+ break-after=,
+ break-before=,
+ keep-with-next=,
+ keep-with-previous=]
+ {\beginXMLelement}
+ {\endXMLelement}
+
+%D Element: fo:table fo:table-caption fo:table-header fo:table-footer
+%D to:table-column fo:table-body fo:table-row fo:table-cell
+
+% \XMLattributeset{fo:aural},
+% border-collapse=,
+% border-separation=,
+% intrusion-displace=,
+% keep-together=,
+% writing-mode=,
+
+\defineXMLenvironment
+ [fo:table]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:relative-position},
+ block-progression-dimension=,
+ border-after-precedence=,
+ border-before-precedence=,
+ border-start-precedence=,
+ border-end-precedence=,
+ break-after=,
+ break-before=,
+ inline-progression-dimension=,
+ height=,
+ keep-with-next=,
+ keep-with-previous=,
+ table-layout=,
+ table-omit-footer-at-break=,
+ table-omit-header-at-break=,
+% text-indent=0pt, % yes or no?
+ width=]
+ {\beginXMLelement
+ \bTABLE % [option=stretch] %
+ \newcounter\FOtablecolumn}
+ {\eTABLE
+ \endXMLelement}
+
+\newdimen\FOtableW
+\newdimen\FOtableH
+
+\defineXMLsingular
+ [fo:table-column]
+ [\XMLattributeset{fo:inherited},
+ \XMLattributeset{fo:border-padding-background}, % only background, not the rest, make subset
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ column-width=,
+ column-number=,
+ number-columns-repeated=,
+ number-columns-spanned=,
+ visibility=]
+ {\directsetup{fo:table-column:action}}
+
+% \XMLattributeset{fo:aural},
+% intrusion-displace=,
+% keep-together=,
+
+\defineXMLprocess
+ [fo:table-caption]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ block-progression-dimension=,
+ height=,
+ inline-progression-dimension=,
+ width=]
+
+% \XMLattributeset{fo:aural},
+
+\defineXMLnested
+ [fo:table-header]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ visibility=]
+ {\beginXMLelement\bTABLEhead}
+ {\eTABLEhead\endXMLelement}
+
+% \XMLattributeset{fo:aural},
+
+\defineXMLnested
+ [fo:table-footer]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ visibility=]
+ {\beginXMLelement\bTABLEfoot}
+ {\eTABLEfoot\endXMLelement}
+
+% \XMLattributeset{fo:aural},
+
+\defineXMLnested
+ [fo:table-body]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ visibility=]
+ {\beginXMLelement\bTABLEbody}
+ {\eTABLEbody\endXMLelement}
+
+% TODO: when stretch and when not
+
+% \XMLattributeset{fo:aural},
+% keep-together=,
+
+\defineXMLnested
+ [fo:table-row]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ break-after=,
+ break-before=,
+ height=,
+ keep-with-next=,
+ keep-with-previous=,
+ visibility=]
+ {\beginXMLelement
+ \directsetup{fo:table-row:start}%
+ \expanded{\bTR[\the\scratchtoks]}%
+ \beginXMLelement}
+ {\endXMLelement
+ \eTR
+ \directsetup{fo:table-row:stop}
+ \endXMLelement}
+
+\startsetups fo:table-row:start
+
+ \inTABLErowtrue
+
+ \scratchtoks\emptytoks
+
+ \doifsomething{\XMLop{height}}
+ {\FOtableH\textheight
+ \setpercentdimen\FOtableH{\XMLop{height}}
+ \appendetoks
+ height=\the\FOtableH
+ \to \scratchtoks}
+
+ \appendetoks
+ ,extras={\rescanXMLattributes{fo:table-row}}
+ \to\scratchtoks
+
+\stopsetups
+
+\startsetups fo:table-row:stop
+
+ \inTABLErowfalse
+
+\stopsetups
+
+% \XMLattributeset{fo:aural},
+% display-align=,
+% relative-align=,
+% empty-cells=,
+
+\newif\ifinTABLErow
+\newdimen\FOtablecellwidth
+\newdimen\FOtablecellheight
+
+\defineXMLnested
+ [fo:table-cell]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:relative-position},
+ border-after-precedence=,
+ border-before-precedence=,
+ border-end-precedence=,
+ border-start-precedence=,
+ column-number=,
+ ends-row=,
+ height=,
+ inline-progression-dimension=,
+ number-columns-spanned=1,
+ number-rows-spanned=1,
+ starts-row=,
+ width=]
+ {\directsetup{fo:table-cell:start}%
+ \expanded{\bTD[\the\scratchtoks]}%
+ \beginXMLelement}
+ {\endXMLelement
+ \eTD
+ \directsetup{fo:table-cell:stop}}
+
+\startsetups fo:table-column:action
+
+ \doifelsenothing{\XMLop{column-number}}
+ {\increment\FOtablecolumn}
+ {\edef\FOtablecolumn{\XMLop{column-number}}
+ \expanded{\setupTABLE[column][\FOtablecolumn][n=\FOtablecolumn]}}
+
+ \doifsomething{\XMLop{column-width}}
+ {%\setlocalhsize
+ %\FOtableW\localhsize
+ \analyzefunction{\XMLop{column-width}}%
+ % hm, we need to set localhsize earlier
+ \doifelse\functionname{proportional-column-width}
+ {\FOtableW\functionA\textwidth}
+ {\FOtableW\textwidth
+ \setpercentdimen\FOtableW{\XMLop{column-width}}}%
+ \expanded{\setupTABLE[column][\FOtablecolumn][width=\the\FOtableW]}}
+
+ \doif{\XMLop{border-style}}{none}
+ {\expanded{\setupTABLE[column][\FOtablecolumn][frame=off]}}
+
+ \doifelsenothing{\XMLop{display-align}}
+ {\doifsomething{\XMLop{text-align}}
+ {\expanded{\setupTABLE[column][\FOtablecolumn]
+ [align=\XMLpav{fo:align-key}{fo:table-column}{text-align}{normal}]}}}
+ {\doifsomething{\XMLop{text-align}}
+ {\expanded{\setupTABLE[column][\FOtablecolumn]
+ [align={\XMLpav{fo:display-align}{fo:table-column}{display-align}{high},\XMLpav{fo:align-key}{fo:table-column}{text-align}{normal}}]}}
+ {\expanded{\setupTABLE[column][\FOtablecolumn]
+ [align=\XMLpav{fo:display-align}{fo:table-column}{display-align}{high}]}}}
+
+\expanded{\setupTABLE[column][\FOtablecolumn][extras={\rescanXMLattributes{fo:table-column}}]}
+
+\stopsetups
+
+\startsetups fo:table-cell:start
+
+ \doif{\XMLop{starts-row}}{true}{\ifinTABLErow\eTR\inTABLErowfalse\fi}
+
+ \ifinTABLErow\else\bTR\inTABLErowtrue\fi
+
+ \doifelsenothing{\XMLop{background-color}}
+ {\let\FoTableBG\empty}
+ {\checkhexcolor[\XMLop{background-color}]
+ \doifcolorelse{\XMLop{background-color}}
+ {\def\FoTableBG{color}}
+ {\setXMLpar{fo:table-cell}{background-color}{}
+ \let\FoTableBG\empty}}
+
+% \doifelse{\XMLpar{fo:table-cell}{width}{}}{}
+% {\def\pFOtablewidth{fit}}
+% {\FOtablecellwidth\textwidth % probably must be localhsize or frozen at an outer level
+% \setpercentdimen\FOtablecellwidth{\XMLpar{fo:table-cell}{width}{0pt}}%
+% \edef\pFOtablewidth{\the\FOtablecellwidth}}%
+
+% \doifelse{\XMLpar{fo:table-cell}{height}{}}{}
+% {\def\pFOtableheight{fit}}
+% {\FOtablecellheight\textheight % probably must be localhsize or frozen at an outer level
+% \setpercentdimen\FOtablecellheight{\XMLpar{fo:table-cell}{height}{0pt}}%
+% \edef\pFOtableheight{\the\FOtablecellheight}}%
+
+ \scratchtoks\emptytoks \appendetoks
+% style=\noexpand\directsetup{fo:font:setup}, % else not expanded
+ nx=\XMLop{number-columns-spanned},
+ ny=\XMLop{number-rows-spanned},
+ n=\XMLop{column-number},
+ background=\FoTableBG
+ \to \scratchtoks
+
+ \doifnot{\XMLop{border-style}}{none}
+ {\appendetoks
+ ,frame=on
+ \to\scratchtoks}
+
+ \doifsomething{\XMLop{background-color}}
+ {\appendetoks
+ ,backgroundcolor=\XMLop{background-color}
+ \to \scratchtoks}
+
+ % todo : padding
+
+ \doifsomething{\XMLop{padding}}
+ {\appendetoks
+ ,offset=\XMLop{padding}
+ \to \scratchtoks}
+
+ % todo: interference with presets in column (outer level) -> \setupcolumn[column] ...;
+ % misschien meerdere align switches
+
+ \doifelsenothing{\XMLop{display-align}}
+ {\doifsomething{\XMLop{text-align}}
+ {\appendetoks
+ ,align=\XMLpav{fo:align-key}{fo:table-cell}{text-align}{normal}
+ \to \scratchtoks}}
+ {\doifsomething{\XMLop{text-align}}
+ {\appendetoks
+ ,align={\XMLpav{fo:display-align}{fo:table-cell}{display-align}{high},\XMLpav{fo:align-key}{fo:table-cell}{text-align}{normal}},
+ \to \scratchtoks}
+ {\appendetoks
+ ,align=\XMLpav{fo:display-align}{fo:table-cell}{display-align}{high}
+ \to \scratchtoks}}
+
+ \appendetoks
+ ,extras={\rescanXMLattributes{fo:table-cell}}
+ \to\scratchtoks
+
+\stopsetups
+
+% \startsetups fo:table-cell:setup
+
+% [\XMLpar{fo:table-cell}{text-indent}{}]
+
+% \edefXMLinhpar\xFOtextindent{fo:table-cell}{text-indent}
+
+% \doifsomething\xFOtextindent
+% {\scratchdimen\hsize
+% \setpercentdimen\scratchdimen\xFOtextindent
+% \expanded{\setupindenting[\the\scratchdimen]}}
+
+% \stopsetups
+
+\startsetups fo:table-cell:stop
+
+ \doif{\XMLop{ends-row}}{true}{\eTR\inTABLErowfalse}
+
+\stopsetups
+
+%D Element: fo:list-block fo:list-item fo:list-body fo:list-item-label
+
+% \XMLattributeset{fo:aural},
+% intrusion-displace=,
+% keep-together=,
+% provisional-distance-between-starts=24pt,
+% provisional-label-separation=6pt,
+
+\defineXMLenvironment
+ [fo:list-block]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:relative-position},
+ break-after=,
+ break-before=,
+ keep-with-next=,
+% space-between-list-rows=, % ? mentioned in bradley
+text-indent=0pt, % yes
+ keep-with-previous=]
+ {\beginXMLelement\directsetup{fo:list:start}}
+ {\directsetup{fo:list:stop}\endXMLelement}
+
+\startsetups fo:list:start
+ \endgraf
+ \begingroup
+ \directsetup{fe:setup}
+ \disablemode[fo:in-list]
+ % \forgetall, no!
+% \directsetup{fo:break-and-space:before}
+ \directsetup{fo:indent:setup}
+ \begingroup
+\stopsetups
+
+\startsetups fo:list:stop
+ \endgraf
+ \endgroup
+% \directsetup{fo:break-and-space:after}
+ \endgroup
+\stopsetups
+
+% \XMLattributeset{fo:aural},
+% relative-align=,
+% intrusion-displace=,
+% keep-together=,
+
+% The list model is plain stupid. Instead of just defining a few mechanism
+% or using some kind of type attribute, a strange mechanism of functions is
+% used. Why on the one hand introduce redundant attributes and on the other
+% hand safe a few elements. A proper segmentation of the problem would have
+% brought better solutions.
+
+\defineXMLenvironment
+ [fo:list-item]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-block},
+ \XMLattributeset{fo:relative-position},
+ break-after=,
+ break-before=,
+ keep-with-next=,
+ keep-with-previous=]
+ {\beginXMLelement\directsetup{fo:list-item:start}}
+ {\directsetup{fo:list-item:stop}\endXMLelement}
+
+% check what is needed
+
+\newdimen\FOlistitemlabelhsize \newdimen\FOlistitembodyhsize \newdimen\FOlistitemdistance
+\newdimen\FOlistitemlabelleftskip \newdimen\FOlistitembodyleftskip
+\newdimen\FOlistitemlabelrightskip \newdimen\FOlistitembodyrightskip
+
+\defineXMLnestedsave
+ [fo:list-item-body]
+ [\XMLattributeset{fo:inherited},
+ id=, % keep-together=,
+ \XMLattributeset{fo:accessibility}]
+
+\defineXMLnestedsave
+ [fo:list-item-label]
+ [\XMLattributeset{fo:inherited},
+ id=, % keep-together=,
+ \XMLattributeset{fo:accessibility}]
+
+\startsetups fo:list-item:start
+
+ \bgroup
+
+% \startmode[fo:in-list]
+% \doifsomething{\XMLpar{fo:list-block}{space-between-list-rows}{}}
+% {\vskip\XMLpar{fo:list-block}{space-between-list-rows}{}} % todo ! ! ! !
+% \stopmode
+
+ \enablemode[fo:in-list]
+
+\stopsetups
+
+% todo : relative-align in list item
+
+\newif\ifFOlabelend
+\newif\ifFObodystart
+
+\startsetups fo:list-item:stop
+
+ % 24pt en 6pt in fo:root instellen
+
+ % \tracebackXMLattribute{provisional-distance-between-starts}
+
+ \edefXMLinh \FOprodis {provisional-distance-between-starts}
+ \edefXMLinh \FOprolab {provisional-label-separation}
+
+% \edef\FOprodis{\XMLpar{fo}{provisional-distance-between-starts}{}}
+% \edef\FOprolab{\XMLpar{fo}{provisional-label-separation}{}}
+
+ \edef\FOprodis{\ifx\FOprodis\empty24pt\else\FOprodis\fi}
+ \edef\FOprolab{\ifx\FOprolab\empty 6pt\else\FOprolab\fi}
+
+ \setlocalhsize
+
+ \FOlistitemlabelleftskip \zeropoint
+ \FOlistitemlabelrightskip\zeropoint
+ \FOlistitembodyleftskip \zeropoint
+ \FOlistitembodyrightskip \zeropoint
+
+ \doifelse{\XMLpar{fo:list-item-label}{end-indent} {}}{label-end()} \FOlabelendtrue \FOlabelendfalse
+ \doifelse{\XMLpar{fo:list-item-body} {start-indent}{}}{body-start()}\FObodystarttrue\FObodystartfalse
+
+ \setpercentdimen\FOlistitemlabelleftskip {\XMLpar{fo:list-item-label}{start-indent}{0pt}}
+ \setpercentdimen\FOlistitembodyrightskip {\XMLpar{fo:list-item-body} {end-indent} {0pt}}
+
+ % maybe i need to implement something configurable
+
+ \ifFObodystart
+ \ifFOlabelend
+ \FOlistitemlabelrightskip\dimexpr(\localhsize-\FOlistitemlabelleftskip-\FOprodis+\FOprolab)
+ \FOlistitembodyleftskip\dimexpr(\FOlistitemlabelleftskip+\FOprodis)
+ \FOlistitemlabelhsize\dimexpr(\FOprodis-\FOprolab)
+ \else
+ \setpercentdimen\FOlistitemlabelrightskip{\XMLpar{fo:list-item-label}{end-indent}{0pt}}
+ \FOlistitemlabelhsize\dimexpr(\localhsize-\FOlistitemlabelleftskip-\FOlistitemlabelrightskip)
+ \FOlistitembodyleftskip\dimexpr(\FOlistitemlabelleftskip+\FOlistitemlabelhsize+\FOprolab)
+ \fi
+ \FOlistitemdistance \dimexpr(\FOprolab)
+ \else
+ \setpercentdimen\FOlistitembodyleftskip{\XMLpar{fo:list-item-body}{start-indent}{0pt}}
+ \ifFOlabelend
+ \FOlistitemlabelrightskip\dimexpr(\localhsize-\FOlistitembodyleftskip+\FOprolab)
+ \FOlistitemlabelhsize\dimexpr(\localhsize-\FOlistitemlabelleftskip-\FOlistitemlabelrightskip)
+ \FOlistitemdistance \dimexpr(\FOprolab)
+ \else
+ \setpercentdimen\FOlistitemlabelrightskip{\XMLpar{fo:list-item-label}{end-indent}{0pt}}
+ \FOlistitemlabelhsize\dimexpr(\localhsize-\FOlistitemlabelleftskip-\FOlistitemlabelrightskip)
+ \FOlistitemdistance \dimexpr(\FOlistitembodyleftskip-\FOlistitemlabelleftskip-\FOlistitemlabelhsize)
+ \fi
+ \fi
+
+ % is this fall back permitted ?
+
+ \ifzeropt\FOlistitemlabelleftskip \ifzeropt\FOlistitemlabelrightskip
+ \FOlistitembodyleftskip\FOprodis
+ \FOlistitemdistance\FOprolab
+ \FOlistitemlabelhsize\dimexpr(\FOlistitembodyleftskip-\FOlistitemdistance)
+ \fi \fi
+
+ %
+
+ \FOlistitembodyhsize\localhsize
+
+ \advance\FOlistitembodyhsize-\FOlistitembodyleftskip
+ \advance\FOlistitembodyhsize-\FOlistitembodyrightskip
+
+ \doifelse{\XMLpar{fo:list-item}{display-align}{}}{center}
+ {\directsetup{fo:list-item:display}}
+ {\directsetup{fo:list-item:text}}
+
+ \egroup
+
+\stopsetups
+
+% todo: textindent
+
+\startsetups fo:list-item:display
+
+ \endgraf
+
+ \advance\leftskip \FOlistitemlabelleftskip
+ \advance\rightskip\FOlistitembodyrightskip
+
+ \dontleavehmode \valign\bgroup\forgetall\vss##\vss\cr
+ \iftracingFO\ruledvtop\else\vbox\fi{\hsize\FOlistitemlabelhsize\directsetup{fo:list-item-label:setup}\XMLflush{fo:list-item-label}}\cr
+ \iftracingFO\ruledvtop\else\vbox\fi{\hsize\FOlistitembodyhsize \directsetup{fo:list-item-body:setup}\XMLflush{fo:list-item-body}}\cr
+ \egroup
+
+% \dontleavehmode \placesidebyside % or maybe paired boxes (legends)
+% {\ruledvtop{\forgetall\hsize\FOlistitemlabelhsize\XMLflush{fo:list-item-label}}}
+% {\ruledvtop{\forgetall\hsize\FOlistitembodyhsize \XMLflush{fo:list-item-body}}}
+
+ \endgraf
+
+\stopsetups
+
+\newtoks\savedeverypar \savedeverypar\everypar
+
+\startsetups fo:list-item:text
+
+ \everypar\savedeverypar % \appendtoksonce\insertparagraphintro\to\everypar % hack, binnen footnote ...
+
+ \advance\leftskip \FOlistitembodyleftskip
+ \advance\rightskip\FOlistitembodyrightskip
+
+ \setupparagraphintro[first][\directsetup{fo:list-item-label:process}]
+ \setupparagraphintro[next] [\begstrut\resetpenalties\clubpenalties]
+ \directsetup{fo:list-item-body:setup}
+ \XMLflush{fo:list-item-body}\endstrut
+
+\stopsetups
+
+\startsetups fo:list-item-label:setups
+
+ \edefXMLinhpar\xFOtextindent{fo:item-label}{text-indent}
+
+ \doifsomething\xFOtextindent
+ {\scratchdimen\hsize
+ \setpercentdimen\scratchdimen\xFOtextindent
+ \expanded{\setupindenting[\the\scratchdimen]}}
+
+\stopsetups
+
+\startsetups fo:list-item-body:setups
+
+ \edefXMLinh\xFOtextindent{fo:item-body}{text-indent}
+
+ \doifsomething\xFOtextindent
+ {\scratchdimen\hsize
+ \setpercentdimen\scratchdimen\xFOtextindent
+ \expanded{\setupindenting[\the\scratchdimen]}}
+
+\stopsetups
+
+\newbox\FOitembox
+
+\startsetups fo:list-item-label:process
+
+ \setbox \FOitembox \iftracingFO \ruledvtop \else \vtop \fi \bgroup
+ \forgetall
+ \postponenotes
+ \hsize\FOlistitemlabelhsize
+ \directsetup{fo:list-item-label:setup}
+ \XMLflush{fo:list-item-label}
+ \egroup
+ \getnoflines{\dimexpr(\ht\FOitembox+\dp\FOitembox)}
+ \setpenalties\clubpenalties\noflines\maxdimen
+ \strut\llap{\box\FOitembox\hskip\FOlistitemdistance}
+
+\stopsetups
+
+% \setlocalhsize \hsize\localhsize
+
+%D Element: fo:basic-link
+
+% \XMLattributeset{fo:aural},
+% keep-together=,
+% line-height=,
+
+\defineXMLenvironmentsave
+ [fo:basic-link]
+ [\XMLattributeset{fo:inherited},
+ id=,
+ \XMLattributeset{fo:accessibility},
+ \XMLattributeset{fo:border-padding-background},
+ \XMLattributeset{fo:margin-inline},
+ \XMLattributeset{fo:relative-position},
+ alignment-adjust=,
+ alignment-baseline=,
+ baseline-shift=,
+ destination-placement-offset=,
+ dominant-baseline=,
+ external-destination=,
+ indicate-destination=,
+ internal-destination=,
+ keep-with-next=,
+ keep-with-previous=,
+ show-destination=,
+ target-processing-context=,
+ target-presentation-context=,
+ target-stylesheet=]
+ {}
+ {\directsetup{fo:basic-link}}
+
+\startsetups fo:basic-link
+
+ \goto{\XMLflushself}[unknown]
+
+\stopsetups
+
+%D Element: fo:multi-switch fo:multi-case fo:multi-toggle fo:multi-properties fo:multi-property-set
+
+\defineXMLprocess[fo:multi-switch]
+\defineXMLprocess[fo:multi-case]
+\defineXMLprocess[fo:multi-toggle]
+\defineXMLprocess[fo:multi-properties]
+\defineXMLprocess[fo:multi-property-set]
+
+%D Element: fo:float
+
+\defineXMLenvironmentsave
+ [fo:float]
+ [\XMLattributeset{fo:inherited},
+ float=before,
+ clear=]
+ {}
+ {\directsetup{fo:float:process}}
+
+% clear: start end left right both none inherit
+% float: before start end left right none
+
+\mapXMLvalue {fo:float-position} {before} {here} % todo
+\mapXMLvalue {fo:float-position} {start} {here} % todo
+\mapXMLvalue {fo:float-position} {end} {here} % todo
+\mapXMLvalue {fo:float-position} {left} {left}
+\mapXMLvalue {fo:float-position} {right} {right}
+\mapXMLvalue {fo:float-position} {none} {here} % todo
+
+\startsetups fo:float:process
+
+ \placefigure
+ [\XMLval{fo:float-position}{\XMLop{float}},none]
+ {}
+ {\XMLflushself}
+
+\stopsetups
+
+%D Element: fo:footnote fo:footnote-body
+
+% Let's assume that 'whatever' contains the number or footnote marker.
+%
+% <fo:footnote>whatever<fo:footnote-body>note</fo:footnote-body></fo:footnote>
+
+% todo xsl-footnote area
+
+\defineXMLprocess
+ [fo:footnote]
+ [\XMLattributeset{fo:accessibility}]
+
+\defineXMLargument
+ [fo:footnote-body]
+ [\XMLattributeset{fo:accessibility}]
+ {\footnote[-]}
+
+%D Element: fo:wrapper
+
+\defineXMLenvironment % todo: all inheritable
+ [fo:wrapper]
+ [\XMLattributeset{fo:inherited},
+ \XMLattributeset{fe:tracing},
+ \XMLattributeset{fo:fonts},
+ \XMLattributeset{fo:hyphenation}]
+ {\beginXMLelement\begingroup\directsetup{fo:wrapper}}
+ {\endgroup\endXMLelement}
+
+\startsetups fo:wrapper
+
+ \directsetup{fe:setup}
+ \directsetup{fo:hyphenation:setup}
+ \directsetup{fo:font:setup}
+
+\stopsetups
+
+%D Element: fo:marker fo:retrieve-marker
+
+% In order to support 'retrieve-boundary' (page, page-sequence,
+% document) I need to extend the context mark handler.
+
+% This object will probably interfere with a too spacy layout since
+% it is unaware if its surrounding.
+
+\defineXMLenvironmentsave
+ [fo:marker]
+ [marker-class-name=unknown]
+ {}
+ {\directsetup{fo:marker:process}}
+
+\startsetups fo:marker:process
+
+ \doifelsemarking{fo:\XMLop{marker-class-name}}
+ {} {\definerawmarking[fo:\XMLop{marker-class-name}]}
+
+ \expanded{\marking[fo:\XMLop{marker-class-name}]{\XMLflushself}}
+
+\stopsetups
+
+\defineXMLcommand
+ [fo:retrieve-marker]
+ [retrieve-class-name=unknown,
+ retrieve-position=first-starting-within-page,
+ retrieve-boundary=]
+ {\directsetup{fo:retrieve-marker:process}}
+
+\mapXMLvalue {fo:marker-position} {first-starting-within-page} {first} % first mark
+\mapXMLvalue {fo:marker-position} {first-including-carryover} {previous} % top mark
+\mapXMLvalue {fo:marker-position} {last-starting-within-page} {first} % dunno
+\mapXMLvalue {fo:marker-position} {last-ending-within-page} {last} % bot mark
+
+\startsetups fo:retrieve-marker:process
+
+ \expanded{\getmarking
+ [fo:\XMLop{retrieve-class-name}]
+ [\XMLval{fo:marker-position}{\XMLop{retrieve-position}}{first}]}
+
+\stopsetups
+
+%D Auxiliary macros
+
+\unprotect
+
+\long\def\noFOchecks#1\od{}
+
+\def\FOassignskip#1#2#3%
+ {\edef\!!stringa{\XMLpar{#1}{#2}\empty}%
+ \edef\!!stringb{\XMLpar{#1}{#2.optimum}\empty}%
+ \edef\!!stringc{\XMLpar{#1}{#2.minimum}\empty}%
+ \edef\!!stringd{\XMLpar{#1}{#2.maximum}\empty}%
+ \dimen0=\ifx\!!stringa\empty\zeropoint\else\!!stringa\fi
+ \dimen2=\ifx\!!stringb\empty\dimen0 \else\!!stringb\fi
+ \dimen4=\dimexpr(\ifx\!!stringd\empty\dimen0 \else\!!stringd\fi-\dimen2)\relax
+ \dimen6=\dimexpr(\ifx\!!stringc\empty\dimen0 \else\!!stringc\fi-\dimen2)\relax
+ #3=\dimen2 \ifzeropt\dimen4 \else\!!plus\dimen4 \fi\ifzeropt\dimen6 \else\!!minus\dimen6 \fi\relax}
+
+\mapXMLvalue{fo:space:conditionality} {retain} {\let\next\retainedskip }
+\mapXMLvalue{fo:space:conditionality} {discard} {\let\next\discardedskip}
+\mapXMLvalue{fo:space:conditionality} {} {\let\next\discardedskip}
+
+\mapXMLvalue{fo:space:precedence} {force} {\let\next\forcedskip}
+
+\def\FOdoskip#1#2%
+ {\begingroup
+ \iftracingFO\showskips\fi
+ \FOassignskip{#1}{#2}\scratchskip
+ \XMLval{fo:space:conditionality}{\XMLpar{#1}{#2.conditionality}\empty}\empty
+ \XMLval{fo:space:precedence}{\XMLpar{#1}{#2.precedence}\empty}\empty
+ \ifdim\scratchskip=\zeropoint
+ \ifdim\gluestretch\scratchskip=\zeropoint
+ \ifdim\glueshrink\scratchskip=\zeropoint
+ \let\next\gobbleoneargument
+ \fi
+ \fi
+ \fi
+ \next\scratchskip
+ \endgroup}
+
+\def\doFObeforeskip#1{\FOdoskip{#1}{space-before}}
+\def\doFOafterskip #1{\FOdoskip{#1}{space-after}}
+
+\def\FOassignspace#1#2#3%
+ {\edef\!!stringa{\XMLpar{#1}{#2}\empty}%
+ \ifx\!!stringa\empty
+ #3=\zeropoint
+ \else
+ #3=1em% ?
+ \setpercentdimen#3\!!stringa
+ \fi
+ \relax}
+
+\def\FOdospace#1#2%
+ {\begingroup
+ \iftracingFO\showskips\fi
+ \FOassignspace{#1}{#2}\scratchskip
+ \ifdim\scratchskip=\zeropoint \else
+ \hskip\scratchskip
+ \fi
+ \endgroup}
+
+\def\doFOstartspace#1{\FOdospace{#1}{space-start}}
+\def\doFOendspace #1{\FOdospace{#1}{space-end}}
+
+\def\checkFOborder#1#2%
+ {\edef\FOattribute{\XMLpar{#1}{border-#2}\empty}%
+ \ifx\FOattribute\empty\else
+ \edef\FOtag{#1}%
+ \edef\FOatt{border-#2}%
+ \expanded{\docheckFOborder\FOattribute\space\relax\space\relax}\od
+ \fi}
+
+\def\docheckFOborder#1#2 #3%
+ {\ifx#1\relax
+ \expandafter\noFOchecks
+ \else
+ \doifhexcolorelse{#1#2}
+ {\setXMLpar\FOtag{\FOatt-color}{#1#2}}
+ {\doifelsenothing{\XMLval{fo:border-style}{#1#2}\empty}
+ {\doifcolorelse{#1#2}
+ {\setXMLpar\FOtag{\FOatt-color}{#1#2}}
+ {\setXMLpar\FOtag{\FOatt-width}{#1#2}}}
+ {\setXMLpar\FOtag{\FOatt-style}{#1#2}}}%
+ \expandafter\docheckFOborder
+ \fi#3}
+
+\def\checkFOposition#1#2%
+ {\edef\FOattribute{\XMLpar{#1}{#2-position}\empty}%
+ \ifx\FOattribute\empty\else
+ \edef\FOtag{#1}%
+ \edef\FOatt{#2-position}%
+ \scratchcounter\zerocount
+ \expanded{\docheckFOposition\FOattribute\space\relax\space\relax}\od
+ \fi}
+
+\def\docheckFOposition#1#2 #3%
+ {\ifx#1\relax
+ \expandafter\noFOchecks
+ \else
+ \advance\scratchcounter\plusone
+ \ifcase\scratchcounter
+ \or
+ \setXMLpar\FOtag{\FOatt-vertical}{#1#2}%
+ \or
+ \setXMLpar\FOtag{\FOatt-horizontal}{#1#2}%
+ \fi
+ \expandafter\docheckFOposition
+ \fi#3}
+
+\def\checkFOpadding{\def\FOatt{padding}\checkFOquadruple}
+\def\checkFOmargin {\def\FOatt{margin}\checkFOquadruple}
+
+\def\checkFOquadruple#1%
+ {\edef\FOattribute{\XMLpar{#1}\FOatt\empty}%
+ \ifx\FOattribute\empty\else
+ \edef\FOtag{#1}%
+ \scratchcounter\zerocount
+ \expanded{\docheckFOquadruple\FOattribute\space\relax\space\relax}\od
+ \ifcase\scratchcounter
+ \let\FOattributeT\FOattribute
+ \let\FOattributeR\FOattribute
+ \let\FOattributeB\FOattribute
+ \let\FOattributeL\FOattribute
+ \or % (tblr)
+ \let\FOattributeT\FOattribute
+ \let\FOattributeR\FOattribute
+ \let\FOattributeB\FOattribute
+ \let\FOattributeL\FOattribute
+ \or % (tb)(lr)
+ \let\FOattributeB\FOattributeT
+ \let\FOattributeL\FOattributeR
+ \or % (t)(lr)(b)
+ \let\FOattributeL\FOattributeR
+ \or % (t)(r)(b)(l)
+ % already ok
+ \fi
+ \letXMLpar\FOtag{\FOatt-top}\FOattributeT
+ \letXMLpar\FOtag{\FOatt-right}\FOattributeR
+ \letXMLpar\FOtag{\FOatt-bottom}\FOattributeB
+ \letXMLpar\FOtag{\FOatt-left}\FOattributeL
+ \fi}
+
+\def\docheckFOquadruple#1#2 #3%
+ {\ifx#1\relax
+ \expandafter\noFOchecks
+ \else
+ \advance\scratchcounter\plusone
+ \ifcase\scratchcounter
+ \or
+ \edef\FOattributeT{#1#2}%
+ \or
+ \edef\FOattributeR{#1#2}%
+ \or
+ \edef\FOattributeB{#1#2}%
+ \or
+ \edef\FOattributeL{#1#2}%
+ \fi
+ \expandafter\docheckFOquadruple
+ \fi#3}
+
+% \def\setFOimagename#1%
+% {\edef\FOimagename{#1}%
+% \aftersplitstring \FOimagename\at url('\to\xFOimagename
+% \ifx\xFOimagename\empty \else
+% \beforesplitstring\xFOimagename\at ')\to\FOimagename
+% \fi
+% \aftersplitstring \FOimagename\at url("\to\xFOimagename
+% \ifx\xFOimagename\empty \else
+% \beforesplitstring\xFOimagename\at ")\to\FOimagename
+% \fi}
+%
+% let's overkill:
+
+\def\setFOimagename#1%
+ {\analyzefunction{#1}%
+ \doifelse\functionname{url}
+ {\edef\FOimagename{\@EA\unstringed\functionA}}
+ {\ifx\functionname\empty
+ \def\FOimagename{#1}%
+ \else
+ \def\FOimagename{dummy}%
+ \fi}}
+
+% font
+
+\mapXMLvalue {fo:weight} {normal} {}
+\mapXMLvalue {fo:weight} {bold} {bold}
+\mapXMLvalue {fo:weight} {bolder} {bold}
+\mapXMLvalue {fo:weight} {lighter} {normal}
+\mapXMLvalue {fo:weight} {100} {normal}
+\mapXMLvalue {fo:weight} {200} {normal}
+\mapXMLvalue {fo:weight} {300} {normal}
+\mapXMLvalue {fo:weight} {400} {normal}
+\mapXMLvalue {fo:weight} {500} {normal}
+\mapXMLvalue {fo:weight} {600} {normal}
+\mapXMLvalue {fo:weight} {700} {normal}
+\mapXMLvalue {fo:weight} {800} {normal}
+\mapXMLvalue {fo:weight} {900} {normal}
+
+\mapXMLvalue {fo:variant} {normal} {}
+\mapXMLvalue {fo:variant} {small-caps} {small-caps}
+
+\mapXMLvalue {fo:style} {normal} {normal}
+\mapXMLvalue {fo:style} {italic} {italic}
+\mapXMLvalue {fo:style} {oblique} {oblique}
+\mapXMLvalue {fo:style} {backslant} {normal}
+
+% we can get crap like: 10pt/1.5 bold "Times Roman" ; i'm really puzzled why an
+% otherwise rather verbose coding occasionally packs attributes; a design flaw
+
+\newtoks\FOfonttoks
+
+\def\checkFOfontSS#1'{}
+\def\checkFOfontDD#1"{}
+\def\checkFOfontII#1 {}
+
+\bgroup
+\catcode`\'=\active
+\catcode`\"=\active
+\catcode`\/=\active
+\gdef\setcheckFOfontX
+ {\catcode`\'=\active
+ \catcode`\"=\active
+ \catcode`\/=\active
+ \def'##1'{\global\FOfonttoks\expandafter{\the\FOfonttoks\def\FOfontfamily{##1}}}%
+ \def"##1"{\global\FOfonttoks\expandafter{\the\FOfonttoks\def\FOfontfamily{##1}}}%
+ \def/##1 {}}% todo linespacing
+\gdef\setcheckFOfontXX
+ {\catcode`\'=\active
+ \catcode`\"=\active
+ \catcode`\/=\active
+ \def'##1'{}%
+ \def"##1"{}%
+ \def/##1 {}}% todo linespacing
+\egroup
+
+\globallet\xFOattribute\empty
+
+\def\checkFOfont#1%
+ {\FOfonttoks\emptytoks
+ \bgroup
+ \catcode`\\=\@@escape
+ \catcode`\{=\@@begingroup
+ \catcode`\}=\@@endgroup
+% \catcode`\:=\@@letter
+% \catcode`\-=\@@letter
+ \setcheckFOfontX
+ \xdef\xFOattribute{#1 }%
+ \setbox\scratchbox\hbox{\scantokens\@EA{\xFOattribute}}%
+ \setcheckFOfontXX
+ \scantokens\@EA{\@EA\xdef\@EA\xFOattribute\@EA{\xFOattribute}}%
+ \egroup
+ \the\FOfonttoks
+ \ifx\xFOattribute\empty\else
+ \expanded{\docheckFOfont\xFOattribute\space\relax\space\relax}\od
+ \fi
+ \directsetup{fo:font:family:check}}
+
+\def\docheckFOfont#1#2 #3%
+ {\ifx#1\relax
+ \expandafter\noFOchecks
+ \else
+ \directsetup{fo:fonts:reset}%
+ \doifelsefontsynonym{#1#2}
+ {\def\FOfontfamily{#1#2}}
+ {\doifelsenothing{\XMLval{fo:weight}{#1#2}{}}
+ {\doifelsenothing{\XMLval{fo:variant}{#1#2}{}}
+ {\doifelsenothing{\XMLval{fo:style}{#1#2}{}}
+ {\setpercentdimen\dFOfontsize{#1#2}}
+ {\edef\FOfontstyle{\XMLval{fo:style}{#1#2}{}}}}
+ {\edef\FOfontvariant{\XMLval{fo:variant}{#1#2}{}}}}
+ {\edef\FOfontweight{\XMLval{fo:weight}{#1#2}{}}}}%
+ \expandafter\docheckFOfont
+ \fi#3}
+
+\protect
+
+\newtoks\FOreferences
+
+\def\setFOreference#1%
+ {\doifsomething{\XMLpar{#1}{id}{}}
+ {\expanded{\appendtoks
+ \noexpand\reference[\XMLpar{#1}{id}{}]{\XMLpar{fo:page-sequence}{format}{}}}%
+ \to\FOreferences}}
+
+\def\flushFOreferences
+ {\the\FOreferences
+ \global\FOreferences\emptytoks}
+
+\def\doFOreference#1%
+ {\doifsomething{\XMLpar{#1}{id}{}}
+ {\expanded{\reference[\XMLpar{#1}{id}{}]{\XMLpar{fo:page-sequence}{format}{}}}}}
+
+\appendtoks \flushFOreferences \to \everypar
+\appendtoks \flushFOreferences \to \neverypar % check !
+
+%D Graphics: static frames
+
+\startMPinclusions
+ input mp-fobg.mpii ;
+\stopMPinclusions
+
+\def\unknownMPcolor{FoNoColor}
+
+% todo: combine into one en alleen tweede run, immers toch geen invloed; is
+% aangezien de referentiepunten vast liggen
+
+\def\FoRegionWidth#1%
+ {\XMLpav
+ {fo:border-width}
+ {fo:region-\MPvar{location}}
+ {border-#1-width}
+ {FoMedium}}
+
+\def\FoRegionStyle#1%
+ {\XMLpav
+ {fo:border-style}
+ {fo:region-\MPvar{location}}
+ {border-#1-style}
+ {FoNone}}
+
+\def\FoRegionColor#1%
+ {\MPcolor{\XMLpar
+ {fo:region-\MPvar{location}}
+ {border-#1-color}
+ {black}}}
+
+\def\FoRegionBackgroundColor
+ {\MPcolor{\XMLpar
+ {fo:region-\MPvar{location}}
+ {background-color}
+ {FoNoColor}}}
+
+% todo: when connected and same color : one draw
+
+\startuseMPgraphic{region-do}
+ FoBackgroundColor := \FoRegionBackgroundColor ;
+ FoLineColor[FoTop] := \FoRegionColor{top} ;
+ FoLineColor[FoBottom] := \FoRegionColor{bottom} ;
+ FoLineColor[FoLeft] := \FoRegionColor{left} ;
+ FoLineColor[FoRight] := \FoRegionColor{right} ;
+ FoLineStyle[FoTop] := \FoRegionStyle{top} ;
+ FoLineStyle[FoBottom] := \FoRegionStyle{bottom} ;
+ FoLineStyle[FoLeft] := \FoRegionStyle{left} ;
+ FoLineStyle[FoRight] := \FoRegionStyle{right} ;
+ FoLineWidth[FoTop] := \FoRegionWidth{top} ;
+ FoLineWidth[FoBottom] := \FoRegionWidth{bottom} ;
+ FoLineWidth[FoLeft] := \FoRegionWidth{left} ;
+ FoLineWidth[FoRight] := \FoRegionWidth{right} ;
+ if FoBackgroundColor <> FoNoColor :
+ fill OverlayBox
+ withcolor FoBackgroundColor ;
+ fi ;
+ path OverlayFrameBox ;
+ interim linecap := butt ;
+ OverlayFrameBox := OverlayBox
+ topenlarged -.5FoLineWidth[FoTop]
+ bottomenlarged -.5FoLineWidth[FoBottom]
+ leftenlarged -.5FoLineWidth[FoLeft]
+ rightenlarged -.5FoLineWidth[FoRight] ;
+ DrawFoFrame(FoTop, topboundary OverlayFrameBox) ;
+ DrawFoFrame(FoBottom, bottomboundary OverlayFrameBox) ;
+ DrawFoFrame(FoLeft, leftboundary OverlayFrameBox) ;
+ DrawFoFrame(FoRight, rightboundary OverlayFrameBox) ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{region-body} \includeMPgraphic{region-do} \stopuseMPgraphic
+\startuseMPgraphic{region-before} \includeMPgraphic{region-do} \stopuseMPgraphic
+\startuseMPgraphic{region-after} \includeMPgraphic{region-do} \stopuseMPgraphic
+\startuseMPgraphic{region-start} \includeMPgraphic{region-do} \stopuseMPgraphic
+\startuseMPgraphic{region-end} \includeMPgraphic{region-do} \stopuseMPgraphic
+
+\startnotmode[fo-no-bg]
+
+\defineoverlay[region-body-graphic] [\useMPgraphic{region-body}{location=body}]
+\defineoverlay[region-before-graphic][\useMPgraphic{region-before}{location=before}]
+\defineoverlay[region-after-graphic] [\useMPgraphic{region-after}{location=after}]
+\defineoverlay[region-start-graphic] [\useMPgraphic{region-start}{location=start}]
+\defineoverlay[region-end-graphic] [\useMPgraphic{region-end}{location=end}]
+
+\stopnotmode
+
+% more efficient: todo: relocate and move to page background
+
+% \def\FoRegionWidth#1#2%
+% {\XMLpav
+% {fo:border-width}
+% {fo:region-#2}
+% {border-#1-width}
+% {FoMedium}}
+
+% \def\FoRegionStyle#1#2%
+% {\XMLpav
+% {fo:border-style}
+% {fo:region-#2}
+% {border-#1-style}
+% {FoNone}}
+
+% \def\FoRegionColor#1#2%
+% {\MPcolor{\XMLpar
+% {fo:region-#2}
+% {border-#1-color}
+% {black}}}
+
+% \def\FoRegionBackgroundColor#1%
+% {\MPcolor{\XMLpar
+% {fo:region-#1}
+% {background-color}
+% {FoNoColor}}}
+
+% \def\combinedFOgraphic#1%
+% {FoBackgroundColor := \FoRegionBackgroundColor{#1} ;
+% FoLineColor[FoTop] := \FoRegionColor{top}{#1} ;
+% FoLineColor[FoBottom] := \FoRegionColor{bottom}{#1} ;
+% FoLineColor[FoLeft] := \FoRegionColor{left}{#1} ;
+% FoLineColor[FoRight] := \FoRegionColor{right}{#1} ;
+% FoLineStyle[FoTop] := \FoRegionStyle{top}{#1} ;
+% FoLineStyle[FoBottom] := \FoRegionStyle{bottom}{#1} ;
+% FoLineStyle[FoLeft] := \FoRegionStyle{left}{#1} ;
+% FoLineStyle[FoRight] := \FoRegionStyle{right}{#1} ;
+% FoLineWidth[FoTop] := \FoRegionWidth{top}{#1} ;
+% FoLineWidth[FoBottom] := \FoRegionWidth{bottom}{#1} ;
+% FoLineWidth[FoLeft] := \FoRegionWidth{left}{#1} ;
+% FoLineWidth[FoRight] := \FoRegionWidth{right}{#1} ;
+% if FoBackgroundColor <> FoNoColor :
+% fill OverlayBox
+% withcolor FoBackgroundColor ;
+% fi ;
+% path OverlayFrameBox ;
+% interim linecap := butt ;
+% OverlayFrameBox := OverlayBox
+% topenlarged -.5FoLineWidth[FoTop]
+% bottomenlarged -.5FoLineWidth[FoBottom]
+% leftenlarged -.5FoLineWidth[FoLeft]
+% rightenlarged -.5FoLineWidth[FoRight] ;
+% DrawFoFrame(FoTop, topboundary OverlayFrameBox) ;
+% DrawFoFrame(FoBottom, bottomboundary OverlayFrameBox) ;
+% DrawFoFrame(FoLeft, leftboundary OverlayFrameBox) ;
+% DrawFoFrame(FoRight, rightboundary OverlayFrameBox) ;}
+
+% \startuseMPgraphic{region-body}
+% \combinedFOgraphic{before}
+% \combinedFOgraphic{body}
+% \combinedFOgraphic{after}
+% \combinedFOgraphic{start}
+% \combinedFOgraphic{end}
+% \stopuseMPgraphic
+
+% \defineoverlay[region-body-graphic] [\useMPgraphic{region-body}{location=body}]
+% \defineoverlay[region-before-graphic][]
+% \defineoverlay[region-after-graphic] []
+% \defineoverlay[region-start-graphic] []
+% \defineoverlay[region-end-graphic] []
+
+\stopXMLcompiling
+
+\endinput
+
+% we can follow two approaches: set the attributes global, using
+%
+% \defineXML...[tag][prefix][empty]
+%
+% in that case we trust the fo-file to be correct, i.e. the xslt style
+% sheets should not put attributes in the wrong places; however, we need
+% to do that with care, since for instance the attributes of some objects
+% (regions) are used mixed
+%
+% \defineXMLprocess [fo:root] [XMLFO] [test=unset]
+%
+% \defineXMLenvironment [fo:block-container] [XMLFO]
+% {\begingroup}
+% {\endgroup}
+%
+% \defineXMLenvironment [fo:block] [XMLFO]
+% {\begingroup\getXMLparameters[XMLFO]\begingroup}
+% {\endgroup\XMLFOtest\endgraf\endgroup}
+%
+% \startXMLdata
+% <fo:root>
+% <fo:block-container test='first'><fo:block test='second'>second:</fo:block></fo:block-container>
+% <fo:block>unset:</fo:block>
+% <fo:block test='outer'><fo:block test='nested'>nested:</fo:block>outer:</fo:block>
+% <fo:block test='last'>last:</fo:block>
+% </fo:root>
+% \stopXMLdata
+%
+% the other approach is to set the attributes explicitly for each
+% element, which is slower but more robust
+%
+% A mix is:
+%
+% \defineXMLenvironment
+% [fo:root]
+% [test=unset]
+% {\beginXMLelement}
+% {\endXMLelement}
+%
+% \defineXMLenvironment
+% [fo:block-container]
+% [test=\XMLpar\XMLpureparent{test}{}]
+% {\beginXMLelement}
+% {\endXMLelement}
+%
+% \defineXMLenvironment
+% [fo:block]
+% [test=\XMLpar\XMLpureparent{test}{}]
+% {\beginXMLelement
+% \begingroup}
+% {\endgroup
+% \XMLpar{fo:block}{test}{}
+% \endXMLelement}
+%
+% \startXMLdata
+% <fo:root>
+% <fo:block-container test='first'><fo:block test='second'>second:</fo:block></fo:block-container>
+% <fo:block>unset:</fo:block>
+% <fo:block test='outer'><fo:block test='nested'>nested:</fo:block>outer:</fo:block>
+% <fo:block test='last'>last:</fo:block>
+% </fo:root>
+% \stopXMLdata
diff --git a/tex/context/modules/mkii/x-foxet.mkii b/tex/context/modules/mkii/x-foxet.mkii
new file mode 100644
index 000000000..d44cf2b7e
--- /dev/null
+++ b/tex/context/modules/mkii/x-foxet.mkii
@@ -0,0 +1,28 @@
+%D \module
+%D [ file=x-foxet,
+%D version=2004.03.12, % based on earlier experiments
+%D title=\FOXET,
+%D subtitle=Formatting Objects,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is just a shortcut for:
+
+% fo = basic formatting objects
+% fe = basic formatting extensions
+% fx = extra formatting objects
+% fu = user formatting objects
+% fs = setup
+
+\usemodule[fo,fe,fx,fu,fs,mathml]
+
+\usemodule[fp] % passivetex bonus
+
+% \autoXMLnamespace[mml,mm,mathml]
+
+\endinput
diff --git a/tex/context/modules/mkii/x-mathml.mkii b/tex/context/modules/mkii/x-mathml.mkii
new file mode 100644
index 000000000..ccb9fa054
--- /dev/null
+++ b/tex/context/modules/mkii/x-mathml.mkii
@@ -0,0 +1,28 @@
+%D \module
+%D [ file=x-mathml,
+%D version=1999.12.20,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Loading \MATHML\ Filters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D We have to make sure that some basic entities are
+%D loaded:
+
+\useXMLfilter[ent]
+
+%D Then we load the math:
+
+\useXMLfilter[mml,mmp,mmc]
+
+%D And we also load the whole bunch of entities:
+
+% \useXMLfilter[mea,meb,mec,meh,men,meo,mer]
+% \useXMLfilter[mxa,mxb,mxc,mxh,mxn,mxo,mxr]
+
+\endinput
diff --git a/tex/context/modules/mkii/x-mathml.xsd b/tex/context/modules/mkii/x-mathml.xsd
new file mode 100644
index 000000000..1c29452b0
--- /dev/null
+++ b/tex/context/modules/mkii/x-mathml.xsd
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xds="http://www.w3.org/?">
+
+<xsd:schema>
+
+<xsd:element name="imath" type="mathml:math" />
+<xsd:element name="dmath" type="mathml:math" />
+
+</xsd:schema>
diff --git a/tex/context/modules/mkii/x-newcml.mkii b/tex/context/modules/mkii/x-newcml.mkii
new file mode 100644
index 000000000..23c2bf1e2
--- /dev/null
+++ b/tex/context/modules/mkii/x-newcml.mkii
@@ -0,0 +1,456 @@
+%D \module
+%D [ file=x-newmml,
+%D version=2006.04.09, % reimplementation
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=ChemML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This used to be an xtag filter using remapping but the
+%D following is nore in sync with the new mathml methods.
+
+\writestatus{loading}{ConTeXt XML Macros / ChemML}
+
+\useXMLfilter[stk]
+
+\unprotect
+
+\def\setupCMLappearance[#1]{\dodoubleargument\getparameters[@@CML#1]}
+
+\defineXMLdirective [chemml] \setupCMLappearance
+
+\defineXMLargument [chem] \automathematics % \rm
+\defineXMLargument [ichem] \inlinemathematics % \rm
+\defineXMLargument [dchem] \displaymathematics % \rm
+
+\def\doifnotXMLparzero#1#2#3%
+ {\ifcase\XMLpar{#1}{#2}{0}\else#3{\XMLpar{#1}{#2}{0}}\fi}
+
+\defineXMLargument [caption] \doCMLcaption
+
+\let\CMLtopcaption\empty
+\let\CMLbotcaption\empty
+
+\chardef\CMLcaptionmode\plusone
+
+\def\doCMLcaption#1%
+ {\ifcase\CMLcaptionmode
+ % can't happen
+ \or
+ \def\CMLbotcaption{#1}%
+ \chardef\CMLcaptionmode\plustwo
+ \or
+ \def\CMLtopcaption{#1}%
+ \chardef\CMLcaptionmode\plusthree
+ \fi}
+
+\def\resetCMLcaption
+ {\let\CMLtopcaption\empty
+ \let\CMLbotcaption\empty
+ \chardef\CMLcaptionmode\plusone}
+
+\resetCMLcaption
+
+\def\doCMLtext#1%
+ {\ifx\CMLtopcaption\empty
+ \setbox0\null
+ \else
+ \setbox0\hbox{\txx\setstrut\strut\ignorespaces\CMLtopcaption\unskip}%
+ \fi
+ \setbox2\hbox{\ignorespaces\strut#1\unskip}%
+ \ifx\CMLbotcaption\empty
+ \setbox4\null
+ \else
+ \setbox4\hbox{\txx\setstrut\strut\ignorespaces\CMLbotcaption\unskip}%
+ \fi
+ \scratchdimen=\wd2\advance\scratchdimen-.5em
+ \ifdim\wd0>\scratchdimen
+ \setbox0\hbox spread .5em{\hss\box0\hss}%
+ \fi
+ \ifdim\wd4>\scratchdimen
+ \setbox4\hbox spread .5em{\hss\box4\hss}%
+ \fi
+ \setbox6=\vbox
+ {\offinterlineskip\halign{\hss##\hss\cr\copy0\cr\copy2\cr\copy4\cr}}%
+ \hbox{\lower\ht4\hbox{\lower\dp2\box6}}}
+
+\def\CMLscript#1%
+ {$\scriptscriptstyle\ignorespaces#1\unskip$}
+
+% \startsetups cml:flush:all
+% \ignorespaces
+% \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
+% \removeunwantedspaces
+% \stopsetups
+
+\newcounter\currentCMLatom
+\newcounter\nofCMLatoms
+
+\defineXMLenvironmentsave
+ [atom]
+ [n=0,weight=0,protons=0,charge=0]
+ {\directsetup{cml:atom:start}}
+ {\directsetup{cml:atom:stop}}
+
+\startsetups cml:atom:start
+ \removeunwantedspaces
+\stopsetups
+
+\startsetups cml:atom:stop
+ \increment\currentCMLatom
+ \resetCMLcaption
+ \doCMLtext {
+ \bgroup
+ \lohi {
+ \doifnotXMLparzero{atom}{protons}\CMLscript
+ } {
+ \doifnotXMLparzero{atom}{weight}\CMLscript
+ }
+ \ignorespaces
+ \XMLflush{atom}
+ \removeunwantedspaces
+ \lohi {
+ \doifnotXMLparzero{atom}{n}\CMLscript
+ } {
+ \ifnum\nofCMLatoms=\currentCMLatom\relax
+ \doifnotXMLparzero{ion}{charge}\CMLscript
+ \else
+ \doifnotXMLparzero{atom}{charge}\CMLscript
+ \fi
+ }
+ \egroup
+ }
+ \ignorespaces
+\stopsetups
+
+\defineXMLnested % why not environment
+ [molecule]
+ [n=0]
+ {\directsetup{cml:molecule:start}}
+ {\directsetup{cml:molecule:stop}}
+
+\startsetups cml:molecule:start
+ \removeunwantedspaces
+ \begingroup
+ \startsavingXMLelements
+ \ignorespaces
+\stopsetups
+
+\startsetups cml:molecule:stop
+ \removeunwantedspaces
+ \stopsavingXMLelements
+ \resetCMLcaption
+ \XMLfirstnamed{caption}
+ \doCMLtext {
+ \newcounter\currentCMLatom
+ \newcounter\nofCMLatoms
+ \doifnotXMLparzero{molecule}{n}\firstofoneargument
+ \ignorespaces
+ \XMLallnamed{atom,ion,bond,singlebond,doublebond,triplebond}
+ \removeunwantedspaces
+ }
+ \endgroup
+ \ignorespaces
+\stopsetups
+
+\setupCMLappearance [ion] [\c!alternative=\v!a]
+
+\defineXMLnested
+ [ion]
+ [n=0,charge=0]
+ {\directsetup{cml:ion:start}}
+ {\directsetup{cml:ion:stop}}
+
+\startsetups cml:ion:start
+ \begingroup
+ \startsavingXMLelements
+\ignorespaces
+\stopsetups
+
+\startsetups cml:ion:stop
+ \removeunwantedspaces
+ \stopsavingXMLelements
+ \resetCMLcaption
+ \XMLfirstnamed{caption}
+ \doCMLtext {
+ \newcounter\currentCMLatom
+ \newcounter\nofCMLatoms
+ \doifnotXMLparzero{ion}{n}\firstofoneargument
+ \doifelse\@@CMLionalternative\v!b {
+ [\ignorespaces
+ \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
+ \removeunwantedspaces]
+ \high {
+ \doifnotXMLparzero{ion}{charge}\CMLscript
+ }
+ } {
+ \countXMLnamedstack{atom}
+ \edef\nofCMLatoms{\the\scratchcounter}% todo: \nofXMLchildren
+ \ignorespaces
+ \XMLallnamed{atom,bond,singlebond,doublebond,triplebond}
+ \removeunwantedspaces
+ }
+ }
+ \endgroup
+ \ignorespaces
+\stopsetups
+
+\let\doCMLsymbol\gobbleoneargument
+\let\doCMLarrow \gobblethreearguments
+
+\defineXMLenvironment
+ [reaction]
+ {\directsetup{cml:reaction:start}}
+ {\directsetup{cml:reaction:stop}}
+
+\startsetups cml:reaction:start
+ \begingroup
+ \let\doCMLsymbol\dodoCMLsymbol
+ \let\doCMLarrow \dodoCMLarrow
+\stopsetups
+
+\startsetups cml:reaction:stop
+ \endgroup
+\stopsetups
+
+\defineXMLcommand [plus] {\doCMLsymbol{+}}
+\defineXMLcommand [minus] {\doCMLsymbol{-}}
+\defineXMLcommand [equal] {\doCMLsymbol{=}}
+
+\def\dodoCMLsymbol#1%
+ {\removeunwantedspaces\quad
+ \mathop{#1}%
+ \quad\kern\zeropoint\ignorespaces}
+
+\defineXMLcommand [gives] {\resetCMLcaption\doCMLgives}
+\defineXMLcommand [equilibrium] {\resetCMLcaption\doCMLequilibrium}
+\defineXMLcommand [mesomeric] {\resetCMLcaption\doCMLmesomeric}
+
+\def\dodoCMLarrow#1%
+ {\removeunwantedspaces\quad
+ \doCMLtext{$\vcenter{\offinterlineskip\halign{##\cr\hskip3em\cr#1\cr}}$}%
+ \quad\kern\zeropoint\ignorespaces}
+
+\def\doCMLgives
+ {\doCMLarrow{\rightarrowfill}}
+
+\def\doCMLequilibrium
+ {\doCMLarrow{\rightarrowfill\cr\noalign{\nointerlineskip}\leftarrowfill}}
+
+\def\doCMLmesomeric
+ {\doCMLarrow{$\leftarrow\hskip-1em$\rightarrowfill}}
+
+\defineXMLcommand [bond] [n=1] \doCMLbond
+\defineXMLcommand [singlebond] [n=1] \doCMLsinglebond
+\defineXMLcommand [doublebond] [n=1] \doCMLdoublebond
+\defineXMLcommand [triplebond] [n=1] \doCMLtriplebond
+
+\def\doCMLbond
+ {\ifcase\XMLop{n}\relax
+ \doCMLsinglebond
+ \or
+ \doCMLdoublebond
+ \or
+ \doCMLtriplebond
+ \fi}
+
+\def\doCMLbond
+ {\removeunwantedspaces
+ \hrule \!!width \hsize \!!height .1ex\relax % .4pt
+ \ignorespaces}
+
+\def\dodoCMLbond#1#2#3%
+ {\removeunwantedspaces
+ \begingroup
+ \setbox\scratchbox\hbox{$M$}%
+ \vbox to \ht\scratchbox
+ {\hsize\wd\scratchbox
+ \vskip.1\wd\scratchbox
+ #1\vfill#2\vfill#3%
+ \vskip.1\wd\scratchbox}%
+ \endgroup
+ \ignorespaces}
+
+\def\doCMLsinglebond{\dodoCMLbond\relax \doCMLbond\relax }
+\def\doCMLdoublebond{\dodoCMLbond\doCMLbond\relax \doCMLbond}
+\def\doCMLtriplebond{\dodoCMLbond\doCMLbond\doCMLbond\doCMLbond}
+
+% extensions (uses m-chemic, which thenneeds to be loaded)
+
+% <dchem>
+% <structure>
+% <component>
+% <graphic>SIX,B</graphic>
+% <graphic>R135</graphic>
+% </component>
+% <component>
+% <graphic>R246</graphic>
+% </component>
+% <component>
+% <graphic>RZ</graphic>
+% <text>A,B,C,D,E,F</text>
+% </component>
+% <component>
+% <graphic>Z</graphic>
+% <oxidation n="3">A</oxidation>
+% <annotation location="tl">
+% <text>B</text>
+% <caption>x</caption>
+% </annotation>
+% <oxidation n="3" sign="+">C</oxidation>
+% <text>D,E,F</text>
+% </component>
+% </structure>
+% <structure>
+% <component>
+% <graphic>SIX,B</graphic>
+% <graphic>r135</graphic>
+% </component>
+% <component>
+% <graphic>R246</graphic>
+% </component>
+% <component>
+% <graphic>RZ</graphic>
+% <text>A,B,C,D,E,F</text>
+% </component>
+% </structure>
+% </dchem>
+
+\ifx\XMLttoks \undefined \newtoks \XMLttoks \fi
+\ifx\XMLgtoks \undefined \newtoks \XMLgtoks \fi
+
+\ifx\startchemical\undefined
+ \def\startchemical {\hbox{module chemic is not loaded}}
+ \let\stopchemical \relax
+ \def\chemical[#1][#2]{}
+\fi
+
+\defineXMLenvironment
+ [structure]
+ {\startchemical
+ \ignorespaces}
+ {\removeunwantedspaces
+ \stopchemical}
+
+\defineXMLenvironment
+ [component]
+ {\global\XMLgtoks\emptytoks
+ \global\XMLttoks\emptytoks
+ \defineXMLargument[graphic]{\dogetCMLgraphic}%
+ \defineXMLargument[text] {\dogetCMLtext}%
+ \ignorespaces}
+ {\removeunwantedspaces
+ \expanded{\chemical[\the\XMLgtoks][\the\XMLttoks]}%
+ \ignorespaces}
+
+\def\dogetCMLgraphic#1%
+ {\doifelsenothing{\the\XMLgtoks}
+ {\uppercase{\doglobal\appendtoks #1\to\XMLgtoks}}
+ {\uppercase{\doglobal\appendtoks,#1\to\XMLgtoks}}%
+ \ignorespaces}
+
+\def\dogetCMLtext#1%
+ {\doifelsenothing{\the\XMLttoks}
+ {\uppercase{\doglobal\appendtoks #1\to\XMLttoks}}
+ {\uppercase{\doglobal\appendtoks,#1\to\XMLttoks}}%
+ \ignorespaces}
+
+\defineXMLargument
+ [oxidation]
+ [sign=,n=1]
+ {\doCMLoxidation}
+
+\def\doCMLoxidation#1%
+ {\expanded{\dogetCMLtext{\noexpand\chemicaloxidation{\XMLop{sign}}{\XMLop{n}}{#1}}}%
+ \ignorespaces}
+
+% \defineXMLenvironment
+% [annotation]
+% [location=]
+% {\defineXMLsave[text]%
+% \defineXMLsave[caption]}
+% {\removeunwantedspaces
+% \processaction
+% [\XMLpar{annotation}{location}{r}]
+% [ t=>\dodoCMLannotation\chemicaltop,
+% b=>\dodoCMLannotation\chemicalbottom,
+% l=>\dodoCMLannotation\chemicalleft,
+% r=>\dodoCMLannotation\chemicalright,
+% lc=>\dodoCMLannotation\chemicalleftcentered,
+% rc=>\dodoCMLannotation\chemicalrightcentered,
+% tl=>\dodoCMLannotation\chemicaltopleft,
+% bl=>\dodoCMLannotation\chemicalbottomleft,
+% tr=>\dodoCMLannotation\chemicaltopright,
+% br=>\dodoCMLannotation\chemicalbottomright,
+% lt=>\dodoCMLannotation\chemicallefttop,
+% lb=>\dodoCMLannotation\chemicalleftbottom,
+% rt=>\dodoCMLannotation\chemicalrighttop,
+% rb=>\dodoCMLannotation\chemicalrightbottom,
+% x=>\dodoCMLannotation\chemicaltighttext,
+% sl=>\dodoCMLannotation\chemicalsmashedleft,
+% sm=>\dodoCMLannotation\chemicalsmashedmiddle,
+% sr=>\dodoCMLannotation\chemicalsmashedright]%
+% \ignorespaces}
+
+% todo: generic mapper t -> top etc
+
+\mapXMLvalue {cml:a:l} {t} {\dodoCMLannotation\chemicaltop}
+\mapXMLvalue {cml:a:l} {b} {\dodoCMLannotation\chemicalbottom}
+\mapXMLvalue {cml:a:l} {l} {\dodoCMLannotation\chemicalleft}
+\mapXMLvalue {cml:a:l} {r} {\dodoCMLannotation\chemicalright}
+\mapXMLvalue {cml:a:l} {lc} {\dodoCMLannotation\chemicalleftcentered}
+\mapXMLvalue {cml:a:l} {rc} {\dodoCMLannotation\chemicalrightcentered}
+\mapXMLvalue {cml:a:l} {tl} {\dodoCMLannotation\chemicaltopleft}
+\mapXMLvalue {cml:a:l} {bl} {\dodoCMLannotation\chemicalbottomleft}
+\mapXMLvalue {cml:a:l} {tr} {\dodoCMLannotation\chemicaltopright}
+\mapXMLvalue {cml:a:l} {br} {\dodoCMLannotation\chemicalbottomright}
+\mapXMLvalue {cml:a:l} {lt} {\dodoCMLannotation\chemicallefttop}
+\mapXMLvalue {cml:a:l} {lb} {\dodoCMLannotation\chemicalleftbottom}
+\mapXMLvalue {cml:a:l} {rt} {\dodoCMLannotation\chemicalrighttop}
+\mapXMLvalue {cml:a:l} {rb} {\dodoCMLannotation\chemicalrightbottom}
+\mapXMLvalue {cml:a:l} {x} {\dodoCMLannotation\chemicaltighttext}
+\mapXMLvalue {cml:a:l} {sl} {\dodoCMLannotation\chemicalsmashedleft}
+\mapXMLvalue {cml:a:l} {sm} {\dodoCMLannotation\chemicalsmashedmiddle}
+\mapXMLvalue {cml:a:l} {sr} {\dodoCMLannotation\chemicalsmashedright}
+
+% \mapXMLvalue {cml:a:l} {cl} {\dodoCMLannotation\chemicalleftcentered}
+% \mapXMLvalue {cml:a:l} {cr} {\dodoCMLannotation\chemicalrightcentered}
+% \mapXMLvalue {cml:a:l} {lt} {\dodoCMLannotation\chemicaltopleft}
+% \mapXMLvalue {cml:a:l} {lb} {\dodoCMLannotation\chemicalbottomleft}
+% \mapXMLvalue {cml:a:l} {rt} {\dodoCMLannotation\chemicaltopright}
+% \mapXMLvalue {cml:a:l} {rb} {\dodoCMLannotation\chemicalbottomright}
+% \mapXMLvalue {cml:a:l} {tl} {\dodoCMLannotation\chemicallefttop}
+% \mapXMLvalue {cml:a:l} {bl} {\dodoCMLannotation\chemicalleftbottom}
+% \mapXMLvalue {cml:a:l} {tr} {\dodoCMLannotation\chemicalrighttop}
+% \mapXMLvalue {cml:a:l} {br} {\dodoCMLannotation\chemicalrightbottom}
+% \mapXMLvalue {cml:a:l} {ls} {\dodoCMLannotation\chemicalsmashedleft}
+% \mapXMLvalue {cml:a:l} {ms} {\dodoCMLannotation\chemicalsmashedmiddle}
+% \mapXMLvalue {cml:a:l} {rs} {\dodoCMLannotation\chemicalsmashedright}
+
+\defineXMLenvironment
+ [annotation]
+ [location=]
+ {\pushXMLmeaning{text}%
+ \pushXMLmeaning{caption}%
+ \defineXMLsave[text]%
+ \defineXMLsave[caption]}
+ {\removeunwantedspaces
+ \XMLval{cml:a:l}{\XMLpar{annotation}{location}{r}}{\XMLflush{text}}%
+ \popXMLmeaning{text}%
+ \popXMLmeaning{caption}%
+ \ignorespaces}
+
+\def\dodoCMLannotation#1%
+ {\expanded{\dogetCMLtext{\noexpand#1{\XMLflush{caption}}{\XMLflush{text}}}}}
+
+\defineXMLenvironment
+ [forever]
+ {\left[}
+ {\right]}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-newmme.mkii b/tex/context/modules/mkii/x-newmme.mkii
new file mode 100644
index 000000000..2e0d4c189
--- /dev/null
+++ b/tex/context/modules/mkii/x-newmme.mkii
@@ -0,0 +1,423 @@
+%D \module
+%D [ file=m-newmme,
+%D version=2005.06.10, % 1999.12.20,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=MathML Entities,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt XML Macros / MathML Entities}
+
+\unprotect
+
+%D Used in the manual:
+
+\def\showMMLentity#1%
+ {\bgroup
+ \doifXMLentityelse{#1}
+ {\let\MMLleft\empty\let\MMLright\empty\mathematics{\getXMLentity{#1}{}}}
+ {\getXMLentity{unknown}}%
+ \egroup}
+
+\newbox\unknownXMLentity
+\setbox\unknownXMLentity\hbox{\inframed[\c!strut=\v!no,\c!offset=1pt]{\ttx ?}}
+
+\defineXMLentity [unknown] {\copy\unknownXMLentity}
+
+%D A (not really needed) precaution:
+
+\ifx\blackboard\undefined
+ \def\blackboard{\ifx\Bbb\undefined\else\expandafter\Bbb\fi}
+\fi
+
+%D Basic entities, greek:
+
+\defineXMLentity [alpha] {\mathematics \alpha}
+\defineXMLentity [beta] {\mathematics \beta}
+\defineXMLentity [gamma] {\mathematics \gamma}
+\defineXMLentity [delta] {\mathematics \delta}
+\defineXMLentity [epsilon] {\mathematics \epsilon}
+\defineXMLentity [zeta] {\mathematics \zeta}
+\defineXMLentity [eta] {\mathematics \eta}
+\defineXMLentity [theta] {\mathematics \theta}
+\defineXMLentity [iota] {\mathematics \iota}
+\defineXMLentity [kappa] {\mathematics \kappa}
+\defineXMLentity [lambda] {\mathematics \lambda}
+\defineXMLentity [theta] {\mathematics \theta}
+\defineXMLentity [mu] {\mathematics \mu}
+\defineXMLentity [nu] {\mathematics \nu}
+\defineXMLentity [xi] {\mathematics \xi}
+\defineXMLentity [pi] {\mathematics \pi}
+\defineXMLentity [rho] {\mathematics \rho}
+\defineXMLentity [sigma] {\mathematics \sigma}
+\defineXMLentity [tau] {\mathematics \tau}
+\defineXMLentity [upsilon] {\mathematics \upsilon}
+\defineXMLentity [phi] {\mathematics \phi}
+\defineXMLentity [chi] {\mathematics \chi}
+\defineXMLentity [psi] {\mathematics \psi}
+\defineXMLentity [omega] {\mathematics \omega}
+
+\defineXMLentity [varepsilon] {\mathematics \varepsilon}
+\defineXMLentity [vartheta] {\mathematics \vartheta}
+\defineXMLentity [varpi] {\mathematics \varpi}
+\defineXMLentity [varrho] {\mathematics \varrho}
+\defineXMLentity [varsigma] {\mathematics \varsigma}
+\defineXMLentity [varphi] {\mathematics \varphi}
+
+\defineXMLentity [epsilonv] {\mathematics \varepsilon}
+\defineXMLentity [thetav] {\mathematics \vartheta}
+\defineXMLentity [piv] {\mathematics \varpi}
+\defineXMLentity [rhov] {\mathematics \varrho}
+\defineXMLentity [sigmav] {\mathematics \varsigma}
+\defineXMLentity [phiv] {\mathematics \varphi}
+
+\defineXMLentity [epsi] {\mathematics \epsilon}
+\defineXMLentity [epsiv] {\mathematics \varepsilon}
+
+\defineXMLentity [Alpha] {A}
+\defineXMLentity [Beta] {B}
+\defineXMLentity [Gamma] {\mathematics \Gamma}
+\defineXMLentity [Delta] {\mathematics \Delta}
+\defineXMLentity [Epsilon] {E}
+\defineXMLentity [Zeta] {Z}
+\defineXMLentity [Eta] {N}
+\defineXMLentity [Theta] {\mathematics \Theta}
+\defineXMLentity [Iota] {I}
+\defineXMLentity [Kappa] {K}
+\defineXMLentity [Lambda] {\mathematics \Lambda}
+\defineXMLentity [Mu] {M}
+\defineXMLentity [Nu] {N}
+\defineXMLentity [Xi] {\mathematics \Xi}
+\defineXMLentity [Pi] {\mathematics \Pi}
+\defineXMLentity [Ro] {R}
+\defineXMLentity [Sigma] {\mathematics \Sigma}
+\defineXMLentity [Tau] {T}
+\defineXMLentity [Upsilon] {\mathematics \Upsilon}
+\defineXMLentity [Phi] {\mathematics \Phi}
+\defineXMLentity [Chi] {X}
+\defineXMLentity [Psi] {\mathematics \Psi}
+\defineXMLentity [Omega] {\mathematics \Omega}
+
+%D Basic entities, hebrew:
+
+\defineXMLentity [aleph] {\mathematics \aleph}
+
+%D Basic entities, functions:
+
+\defineXMLentity [abs] {\mathopnolimits{abs}}
+\defineXMLentity [arg] {\mathopnolimits{arg}}
+\defineXMLentity [codomain] {\mathopnolimits{codomain}}
+\defineXMLentity [curl] {\mathopnolimits{curl}}
+\defineXMLentity [determinant] {\mathopnolimits{det}}
+\defineXMLentity [divergence] {\mathopnolimits{div}}
+\defineXMLentity [domain] {\mathopnolimits{domain}}
+\defineXMLentity [false] {\mathopnolimits{false}}
+\defineXMLentity [gcd] {\mathopnolimits{gcd}}
+\defineXMLentity [grad] {\mathopnolimits{grad}}
+\defineXMLentity [identity] {\mathopnolimits{id}}
+\defineXMLentity [image] {\mathopnolimits{image}}
+\defineXMLentity [lcm] {\mathopnolimits{lcm}}
+\defineXMLentity [max] {\mathopnolimits{max}}
+\defineXMLentity [median] {\mathopnolimits{median}}
+\defineXMLentity [min] {\mathopnolimits{min}}
+\defineXMLentity [mode] {\mathopnolimits{mode}}
+\defineXMLentity [mod] {\mathopnolimits{mod}}
+\defineXMLentity [notanumber] {\mathopnolimits{NaN}}
+\defineXMLentity [otherwise] {\mathopnolimits{otherwise}}
+\defineXMLentity [true] {\mathopnolimits{true}}
+\defineXMLentity [declare] {\mathopnolimits{declare}}
+\defineXMLentity [as] {\mathopnolimits{as}}
+\defineXMLentity [polar] {\mathopnolimits{Polar}}
+
+\defineXMLentity [mathematicald] {d}
+
+\defineXMLentity [imaginaryi] {{\rm i}}
+\defineXMLentity [differentiald] {\partial}
+\defineXMLentity [exponentiale] {{\rm e}}
+\defineXMLentity [capitaldifferentiald] {D}
+
+\defineXMLentity [ii] {\getXMLentity{imaginaryi}}
+\defineXMLentity [dd] {\getXMLentity{differentiald}}
+\defineXMLentity [ee] {\getXMLentity{exponentiale}}
+\defineXMLentity [DD] {\getMMLentity{capitaldifferentiald}}
+
+\defineXMLentity [ImaginaryI] {\getXMLentity{imaginaryi}}
+\defineXMLentity [DifferentialD] {\getXMLentity{differentiald}}
+\defineXMLentity [ExponentialE] {\getXMLentity{exponentiale}}
+\defineXMLentity [CapitalDifferentialD] {\getXMLentity{differentiald}}
+
+\defineXMLentity [NaN] {\getXMLentity{notanumber}}
+\defineXMLentity [NotANumber] {\getXMLentity{notanumber}}
+
+\defineXMLentity [and] {\wedge}
+\defineXMLentity [exists] {\exists}
+\defineXMLentity [forall] {\forall}
+\defineXMLentity [implies] {\Rightarrow}
+\defineXMLentity [not] {\neg}
+\defineXMLentity [or] {\vee}
+\defineXMLentity [xor] {\mathopnolimits{xor}}
+
+\defineXMLentity [imaginary] {\Im}
+\defineXMLentity [real] {\Re}
+
+\defineXMLentity [lceiling] {\lceil}
+\defineXMLentity [rceiling] {\rceil}
+
+\defineXMLentity [lfloor] {\lfloor}
+\defineXMLentity [rfloor] {\rfloor}
+
+\defineXMLentity [ne] {\neq}
+\defineXMLentity [neq] {\neq}
+\defineXMLentity [gt] {>}
+\defineXMLentity [lt] {<}
+\defineXMLentity [ge] {\geq}
+\defineXMLentity [geq] {\geq}
+\defineXMLentity [le] {\leq}
+\defineXMLentity [leq] {\leq}
+
+\defineXMLentity [equivalent] {\equiv}
+\defineXMLentity [equiv] {\equiv}
+\defineXMLentity [approx] {\approx}
+
+\defineXMLentity [factorof] {\mid}
+\defineXMLentity [mapsto] {\mapsto}
+
+\defineXMLentity [int] {\int}
+\defineXMLentity [prime] {\prime}
+\defineXMLentity [laplacian] {\nabla^2}
+\defineXMLentity [partial] {\partial}
+
+\defineXMLentity [union] {\cup}
+\defineXMLentity [intersect] {\cap}
+\defineXMLentity [in] {\in}
+\defineXMLentity [notin] {\not\in}
+\defineXMLentity [subset] {\subset}
+\defineXMLentity [prsubset] {\subseteq}
+\defineXMLentity [notsubset] {\not\subset}
+\defineXMLentity [notprsubset] {\not\subseteq}
+\defineXMLentity [setdiff] {\setminus}
+
+\defineXMLentity [card] {\vert}
+\defineXMLentity [cartesianproduct] {\times}
+
+\defineXMLentity [sum] {\sum}
+\defineXMLentity [prod] {\prod}
+\defineXMLentity [product] {\prod}
+\defineXMLentity [lim] {\lim}
+
+\defineXMLentity [exp] {\mathopnolimits{exp}} % {\exp}
+\defineXMLentity [ln] {\mathopnolimits{ln}} % {\ln}
+\defineXMLentity [log] {\mathopnolimits{log}} % {\log}
+
+\defineXMLentity [sin] {\mathopnolimits{sin}}
+\defineXMLentity [arcsin] {\mathopnolimits{arcsin}}
+\defineXMLentity [sinh] {\mathopnolimits{sinh}}
+\defineXMLentity [arcsinh] {\mathopnolimits{arcsinh}}
+\defineXMLentity [cos] {\mathopnolimits{cos}}
+\defineXMLentity [arccos] {\mathopnolimits{arccos}}
+\defineXMLentity [cosh] {\mathopnolimits{cosh}}
+\defineXMLentity [arccosh] {\mathopnolimits{arccosh}}
+\defineXMLentity [tan] {\mathopnolimits{tan}}
+\defineXMLentity [arctan] {\mathopnolimits{arctan}}
+\defineXMLentity [tanh] {\mathopnolimits{tanh}}
+\defineXMLentity [arctanh] {\mathopnolimits{arctanh}}
+\defineXMLentity [cot] {\mathopnolimits{cot}}
+\defineXMLentity [arccot] {\mathopnolimits{arccot}}
+\defineXMLentity [coth] {\mathopnolimits{coth}}
+\defineXMLentity [arccoth] {\mathopnolimits{arccoth}}
+\defineXMLentity [csc] {\mathopnolimits{csc}}
+\defineXMLentity [arccsc] {\mathopnolimits{arccsc}}
+\defineXMLentity [csch] {\mathopnolimits{csch}}
+\defineXMLentity [arccsch] {\mathopnolimits{arccsch}}
+\defineXMLentity [sec] {\mathopnolimits{sec}}
+\defineXMLentity [arcsec] {\mathopnolimits{arcsec}}
+\defineXMLentity [sech] {\mathopnolimits{sech}}
+\defineXMLentity [arcsech] {\mathopnolimits{arcsech}}
+
+\defineXMLentity [transpose] {^{\rm T}}
+
+\defineXMLentity [plusminus] {\mathematics{\pm}}
+\defineXMLentity [minusplus] {\mathematics{\mp}}
+
+\defineXMLentity [vectorproduct] {\times}
+\defineXMLentity [scalarproduct] {\cdot}
+\defineXMLentity [outerproduct] {\otimes}
+
+\defineXMLentity [integers] {\integers}
+\defineXMLentity [reals] {\reals}
+\defineXMLentity [rationals] {\rationals}
+\defineXMLentity [naturalnumbers] {\naturalnumbers}
+\defineXMLentity [complexes] {\complexes}
+\defineXMLentity [primes] {\primes}
+
+\defineXMLentity [emptyset] {\emptyset}
+\defineXMLentity [pi] {\pi}
+\defineXMLentity [eulergamma] {\gamma}
+\defineXMLentity [infinity] {\mathematics{\infty}}
+
+\defineXMLentity [InvisibleTimes] {}
+\defineXMLentity [InvisibleComma] {}
+\defineXMLentity [ApplyFunction] {}
+
+\defineXMLentity [it] {\getXMLentity{InvisibleTines}}
+\defineXMLentity [ic] {\getXMLentity{InvisibleComma}}
+\defineXMLentity [af] {\getXMLentity{ApplyFunction}}
+
+\defineXMLentity [PlusMinus] {\getXMLentity{plusminus}}
+
+\defineXMLentity [infin] {\getXMLentity{infinity}}
+\defineXMLentity [infty] {\getXMLentity{infinity}}
+\defineXMLentity [part] {\getXMLentity{differentiald}}
+
+\defineXMLentity [RightArrow] {\normalorfiller\rightarrow\rightarrowfill}
+\defineXMLentity [LeftArrow] {\normalorfiller\leftarrow\leftarrowfill}
+\defineXMLentity [UnderBrace] {\normalorfiller\empty\upbracefill}
+\defineXMLentity [OverBrace] {\normalorfiller\empty\downbracefill}
+\defineXMLentity [UnderBar] {\normalorfiller\hrule\hrulefill}
+\defineXMLentity [OverBar] {\normalorfiller\hrule\hrulefill}
+\defineXMLentity [Hat] {\normalorfiller\empty\empty} % todo
+
+\defineXMLentity [downarrow] {\mathortext\downarrow\empty}
+\defineXMLentity [uparrow] {\mathortext\uparrow\empty}
+
+\defineXMLentity [Tab] {\hskip4em}
+\defineXMLentity [NewLine] {\mathortext\empty\crlf}
+\defineXMLentity [IndentingNewLine] {\mathortext\empty\crlf}
+
+\defineXMLentity [NoBreak] {\nobreak}
+\defineXMLentity [GoodBreak] {\goodbreak}
+\defineXMLentity [BadBreak] {\nobreak}
+
+\defineXMLentity [Space] {\getXMLentity{MediumSpace}}
+\defineXMLentity [NonBreakingSpace] {\getXMLentity{MediumSpace}}
+\defineXMLentity [ZeroWidthSpace] {}
+
+\def\somespaceentity#1#2%
+ {\mathortext
+ {\mskip#1mu}
+ {\ifvmode\dontleavehmode\else\unskip\fi\hskip#2em\strut\hskip\zeropoint\ignorespaces}%
+ \relax}
+
+\defineXMLentity [VeryThinSpace] {\somespaceentity {2}{.125}}
+\defineXMLentity [ThinSpace] {\somespaceentity {3}{.25}}
+\defineXMLentity [MediumSpace] {\somespaceentity {4}{.5}}
+\defineXMLentity [ThickSpace] {\somespaceentity {5}{1}}
+\defineXMLentity [NegativeVeryThinSpace] {\somespaceentity{-2}{-.125}}
+\defineXMLentity [NegativeThinSpace] {\somespaceentity{-3}{-.25}}
+\defineXMLentity [NegativeMediumSpace] {\somespaceentity{-4}{-.5}}
+\defineXMLentity [NegativeThickSpace] {\somespaceentity{-5}{-1}}
+
+\defineXMLentity [NegVeryThinSpace] {\getXMLentity{NegativeVeryThinSpace}}
+\defineXMLentity [NegThinSpace] {\getXMLentity{NegativeThinSpace}}
+\defineXMLentity [NegMediumSpace] {\getXMLentity{NegativeMediumSpace}}
+\defineXMLentity [NegThickSpace] {\getXMLentity{NegativeThickSpace}}
+
+\defineXMLentity [nbsp] {\getXMLentity{NonBreakingSpace}}
+\defineXMLentity [thinsp] {\getXMLentity{ThinSpace}}
+\defineXMLentity [medsp] {\getXMLentity{MediumSpace}}
+\defineXMLentity [thicksp] {\getXMLentity{ThickSpace}}
+
+\defineXMLentity [larr] {\getXMLentity{LeftArrow}}
+\defineXMLentity [rarr] {\getXMLentity{RightArrow}}
+
+\ifx\MMLleft \undefined \let\MMLleft \firstofoneargument \fi
+\ifx\MMLright\undefined \let\MMLright\firstofoneargument \fi
+
+\defineXMLentity [lbrace] {\normalordelimiter{\{}{\MMLleft \{}}
+\defineXMLentity [rbrace] {\normalordelimiter{\}}{\MMLright\}}}
+\defineXMLentity [lbracket] {\normalordelimiter{[}{\MMLleft [}}
+\defineXMLentity [rbracket] {\normalordelimiter{]}{\MMLright]}}
+\defineXMLentity [lparenthesis] {\normalordelimiter{(}{\MMLleft (}}
+\defineXMLentity [rparenthesis] {\normalordelimiter{)}{\MMLright)}}
+\defineXMLentity [langle] {\normalordelimiter{\langle}{\MMLleft \langle}}
+\defineXMLentity [rangle] {\normalordelimiter{\rangle}{\MMLright\rangle}}
+
+\defineXMLentity [lang] {\getXMLentity{langle}}
+\defineXMLentity [rang] {\getXMLentity{rangle}}
+\defineXMLentity [lbrack] {\getXMLentity{lbracket}}
+\defineXMLentity [rbrack] {\getXMLentity{rbracket}}
+\defineXMLentity [lparent] {\getXMLentity{lparenthesis}}
+\defineXMLentity [rparent] {\getXMLentity{rparenthesis}}
+
+\defineXMLentity [\letterleftbrace ] {\getXMLentity{lbrace}}
+\defineXMLentity [\letterrightbrace] {\getXMLentity{rbrace}}
+
+\defineXMLentity [{[}] {\getXMLentity{lbracket}}
+\defineXMLentity [{]}] {\getXMLentity{rbracket}}
+\defineXMLentity [{(}] {\getXMLentity{lparenthesis}}
+\defineXMLentity [{)}] {\getXMLentity{rparenthesis}}
+
+
+\defineXMLentity [times] {\mathematics{\times}}
+\defineXMLentity [minus] {\mathematics{-}}
+\defineXMLentity [plus] {\mathematics{+}}
+\defineXMLentity [plusmn] {\mathematics{\pm}}
+
+\defineXMLentity [nabla] {\nabla}
+
+\def\myspecialnormalvert {\mathematics{\vert}}
+\def\myspecialstretchvert{\;\vrule\;}
+
+\defineXMLentity [,] {{,}}
+\defineXMLentity [.] {{.}}
+\defineXMLentity [+] {+}
+\defineXMLentity [-] {-}
+\defineXMLentity [|] {\myspecialnormalvert}
+\defineXMLentity [/] {/}
+\defineXMLentity [*] {\times}
+\defineXMLentity [=] {=}
+
+% \defineXMLentity [(] {(}
+% \defineXMLentity [)] {)}
+% \defineXMLentity [<] {\mathematics{<}}
+% \defineXMLentity [>] {\mathematics{>}}
+
+% \defineXMLentity [(] {\MMLleft (}
+% \defineXMLentity [)] {\MMLright)}
+
+% \defineXMLentity [{[}] {\MMLleft [}
+% \defineXMLentity [{]}] {\MMLright]}
+
+\defineXMLentity [++] {++}
+\defineXMLentity [--] {--}
+\defineXMLentity [//] {//}
+\defineXMLentity [**] {\times\times}
+\defineXMLentity [==] {==}
+\defineXMLentity [...] {\cdots}
+
+\defineXMLentity [quot] {"}
+
+\defineXMLentity [triangle] {\mathematics\triangle}
+\defineXMLentity [otimes] {\mathematics\otimes}
+\defineXMLentity [oplus] {\mathematics\oplus}
+\defineXMLentity [cup] {\mathematics\cup}
+\defineXMLentity [cap] {\mathematics\cap}
+\defineXMLentity [sdot] {\mathematics\cdot}
+\defineXMLentity [dot] {\mathematics\cdot}
+\defineXMLentity [sim] {\mathematics\sim}
+\defineXMLentity [circ] {\mathematics\circ}
+\defineXMLentity [dagger] {\mathematics\dagger}
+\defineXMLentity [cdots] {\mathematics\cdots}
+
+\defineXMLentity [...] {\getXMLentity{cdots}}
+\defineXMLentity [continued] {\getXMLentity{cdots}}
+
+\defineXMLentity [sub] {\getXMLentity{subset}}
+\defineXMLentity [sube] {\getXMLentity{prsubset}}
+\defineXMLentity [notprsubset] {\getXMLentity{notprsubset}}
+
+\defineXMLentity [ndash] {\endash}
+\defineXMLentity [mdash] {\emdash}
+
+\defineXMLentity [tex-bar] {\mathematics{\vert}}
+\defineXMLentity [tex-dollar] {\dollar}
+\defineXMLentity [tex-backslash] {\backslash}
+\defineXMLentity [tex-leftbrace] {\mathematics{\{}}
+\defineXMLentity [tex-rightbrace] {\mathematics{\}}}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-newmml.mkii b/tex/context/modules/mkii/x-newmml.mkii
new file mode 100644
index 000000000..e777edca1
--- /dev/null
+++ b/tex/context/modules/mkii/x-newmml.mkii
@@ -0,0 +1,2744 @@
+%D \module
+%D [ file=x-newmml,
+%D version=2005.06.10, % 1999.12.20,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=MathML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Remark: from now on this is a module and no longer an xtag
+%D filter. In due time it will replace the older renderer (which
+%D we will keep around for sentimental reasons). This variant has
+%D no namespace support yet, but eventually we will use a \MKIV\
+%D version.
+
+\useXMLfilter[stk]
+
+\ifx\inlinemathematics\undefined
+ \def\inlinemathematics {\dontleavehmode\mathematics} % already in kernel
+ \long\def\inlinemath #1{\dontleavehmode\relax\ifmmode#1\else $#1$\fi}
+\fi
+
+% \defineXMLentity[x000AF]{\normalorfiller{x}\hrulefill}
+% CHECK FOR: \xmlrent
+% \enablemathpunctuation
+
+%D Then we start defining the rendering macros:
+
+\writestatus{loading}{ConTeXt XML Macros / MathML}
+
+\startmodule [mathml]
+
+%D First we load the entities:
+
+\usemodule[newmme]
+
+% \setupmodule[a=c]
+% \setupmodule[a=c]
+
+\unprotect
+
+\def\MMLrm{\mr}
+
+\def\MMLseparator#1{{#1}} % nils space after separator
+
+%D First we define some general formula elements.
+
+\defineXMLenvironment [formula] [label=,sublabel=]
+ {\dostartXMLformula\placeformula}
+ {\dostopXMLformula}
+
+\defineXMLenvironment [subformula] [label=,sublabel=]
+ {\dostartXMLformula\placesubformula}
+ {\dostopXMLformula}
+
+\def\dostartXMLformula#1%
+ {\doifelsenothingXMLop{label}
+ {\startformula}
+ {\expanded{#1[\XMLop{label}]{\XMLop{sublabel}}}\startformula}}
+
+\def\dostopXMLformula
+ {\stopformula}
+
+%D Since I only had the draft of MathML 2 as example of
+%D rendering, there are probably a lot of omissions and
+%D misinterpretations. At least I learned some bits and
+%D pieces of math rendering.
+%D
+%D The main complications were not so much the math, but to
+%D find the most efficient way to handle elements without
+%D spacing beging messed up. The first implementation was
+%D aimed at getting reasonable output, this second
+%D implementation is already better in terms of handling
+%D nesting, and I will definitely need a third one that has
+%D more efficient and less ugly code.
+%D
+%D The \TEX\ part is not that complicated and once the
+%D preprocessor was okay, the rest way just a lot of keying
+%D and testing. It all comes down to gobbling, redefining,
+%D and not so much to parsing.
+%D
+%D The second implementation expanded the whole math sequence
+%D into an internal \TEX\ representation. This is a rather clean
+%D and fast process. Filtering and testing takes place by
+%D redefining the internal representation macros.
+%D
+%D The third implementation may look a bit more messy in some
+%D respects. This is because in \TEX\ it's not that trivial to
+%D implement a tree handler. We use a stack for the \type {apply}
+%D element and other sequential content. Occasionally we need to
+%D peek into child elements which involves messy code. This
+%D implementation is closer to the normal \XML\ handling in
+%D \CONTEXT.
+
+%D We start with the parent elements and the option handler.
+
+\defineXMLdirective [mathml] \setupMMLappearance
+
+\defineXMLargument [math] \automathematics
+\defineXMLargument [imath] \inlinemathematics
+\defineXMLargument [dmath] \displaymathematics
+\defineXMLargument [m] \inlinemathematics
+
+%D In the styles, options can be set with:
+
+\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[@@MML#1]}
+
+\def\startusingMMLarguments % optional maken
+ {\begingroup
+ %\expandXMLta % expand entities first
+ \getXMLta}
+
+\def\stopusingMMLarguments % optional maken
+ {\endgroup}
+
+\def\MMLargumentprefix{@@MML\currentXMLelement}
+
+%D We will apply inner math to all bits and pieces made up by an
+%D \type {apply}.
+
+\def\MMLmathinner
+ {\ifinner \expandafter \firstofoneargument \else \expandafter \mathinner \fi}
+
+%D A few math related macros:
+
+\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist}
+
+\newcount\MMLapplydepth \def\MMLcreset{\MMLapplydepth\zerocount}
+
+% Stack handler
+
+\startXMLmapping[xmlstack:test]
+
+ \defineXMLnested
+ [apply]
+ {\startsavingXMLelements}
+ {\stopsavingXMLelements}
+
+\stopXMLmapping
+
+%D Auxiliary MathML macros: (to be generalized)
+
+\def\doifelseMMCfunction
+ {\begingroup
+ \XMLdoifonstackelse{fn}
+ {\donetrue}
+ {\XMLdoifonstackelse{apply}
+ {\defXMLfirstnamedtext\ascii{apply}%
+ \startsavingXMLelements % best use a substack so that we do not need to \edef
+ \ascii
+ \stopsavingXMLelements}
+ {}%
+ \XMLdoifonstackelse{fn}
+ {\donetrue}
+ {\defineXMLsave[ci][type=]%
+ \XMLfirstnamed{ci}%
+ \doifelse{\XMLpar{ci}{type}{}}{fn}
+ {\donetrue}
+ {\donefalse}}}%
+ \ifdone
+ \endgroup\expandafter\firstoftwoarguments
+ \else
+ \endgroup\expandafter\secondoftwoarguments
+ \fi}
+
+\def\doifelseMMCfunctioninapply#1#2% grouped
+ {\begingroup
+ \startXMLmapping[xmlstack:test]% take fast alternative
+ \getXMLstackdata{#1}%
+ \expanded{\doifinsetelse{\getXMLstackname\plusone}{#2}}
+ {\stopXMLmapping
+ \endgroup\firstoftwoarguments }
+ {\stopXMLmapping
+ \endgroup\secondoftwoarguments}}
+
+\def\dodoifelseMMCfunctioninapply#1#2%
+ {\startXMLmapping[xmlstack:test]% take fast alternative
+ \getXMLstackdata{#1}%
+ \expanded{\doifinsetelse{\getXMLstackname\plusone}{#2}}
+ {\stopXMLmapping
+ \firstoftwoarguments }
+ {\stopXMLmapping
+ \secondoftwoarguments}}
+
+%D Special features:
+
+\newtoks \@@postponedMMLactions \setfalse \somepostponedMMLactions
+
+\def\postponeMMLactions#1%
+ {\global\settrue\somepostponedMMLactions
+ \global\@@postponedMMLactions\expandafter{\the\@@postponedMMLactions#1}}
+
+\def\postponedMMLactions
+ {\global\setfalse\somepostponedMMLactions
+ \@EA\global\@EA\@@postponedMMLactions\@EA\emptytoks
+ \the\@@postponedMMLactions}
+
+%D A couple of lists:
+
+\def\MMLcmainresetlist
+ {times,divide,power,%
+ lt,gt,eq,leq,geq,%
+ in,inverse,%
+ fn,%
+ floor,ceiling,%
+ mean,%
+ selector,%
+ abs,int,limit,sum,product,%
+ outerproduct,innerproduct,scalarproduct}
+
+\def\MMLcfunctionlist
+ {sin,arcsin,sinh,arcsinh,%
+ cos,arccos,cosh,arccosh,%
+ tan,arctan,tanh,arctanh,%
+ cot,arccot,coth,arccoth,%
+ csc,arccsc,csch,arccsch,%
+ sec,arcsec,sech,arcsech,%
+ ln,exp,log,%
+ abs,int,limit,sum,product,%
+ fn} % ?
+
+\def\MMLcconstructlist
+ {diff,partialdiff,root} % apply goes wrong on 1/2 * (a_2 + b_3)
+
+% apply
+%
+%D We use inner and grouping (begin/end and no b/e) else we
+%D get problems with 1/2(1+2) and alike (todo: ask taco).
+%D
+%D The problem with apply is that we need to take care of
+%D several situations, like:
+%D
+%D \starttyping
+%D <apply> <.../> ...
+%D <apply> <fn> ...
+%D <apply> <apply> <ci> ...
+%D <apply> <apply> <fn> <ci> ...
+%D \stoptyping
+%D
+%D Because we translated version 2 of this renderer into
+%D version 3 the following definitions may be sub optimal or
+%D more complex than actually needed.
+
+\defineXMLnested % why nested? could be just an environment
+ [apply]
+ [open=,close=]
+ {\setups{mmc:apply:start}}
+ {\setups{mmc:apply:stop}}
+
+\startsetups mmc:apply:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:apply:stop
+ \stopsavingXMLelements
+ \MMLmathinner {
+ \expanded{\doifinsetelse{\getXMLstackname\plusone}{\MMLcmainresetlist,\MMLctempresetlist}}
+ \MMLcreset
+ \donothing
+ \ifcase\MMLapplydepth \else
+ \doifXMLparelse{apply}{open} \donothing{\getXMLarguments{apply}{open="("}}% slow
+ \doifXMLparelse{apply}{close}\donothing{\getXMLarguments{apply}{close=")"}}% slow
+ \fi
+ \doifXMLparelse{apply}{open}{\left\XMLpar{apply}{open}{}}\donothing
+ \advance\MMLapplydepth\plusone
+ \begingroup
+ \let\MMLctempresetlist\empty
+ \doifelse {\getXMLstackname\plusone} {apply} {
+ % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
+ \doifelseMMCfunctioninapply \plusone {plus,minus} {
+ % yet incomplete and rather untested
+ % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
+ } {
+ \MMLcreset
+ }
+ \getXMLstackdata\plusone
+ \ifconditional\somepostponedMMLactions
+ \postponedMMLactions
+ \else
+ \left(\MMLcreset\getXMLstackdata\plustwo\right)
+ \fi
+ } {
+ \doifelse {\getXMLstackname\plusone} {fn} {
+ % also postpone
+ \directsetup{mmc:fn:apply}
+ } {
+ \doifelse {\getXMLstackname\plusone} {csymbol} {
+ % also postpone
+ \directsetup{mmc:csymbol:apply}
+ } {
+ \doifelse {\getXMLstackname\plusone} {ci} {
+ \getXMLstackdata\plusone
+ \ifnum\XMLstacklevel>\plusone
+ \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)
+ \fi
+ } {
+ \getXMLstackdata\plusone
+ }
+ }
+ }
+ }
+ \endgroup
+ \advance\MMLapplydepth\minusone
+ \directsetup{apply:flush}
+ \doifXMLparelse{apply}{close}{\right\XMLpar{apply}{close}{}}\donothing
+ }
+ \endgroup
+\stopsetups
+
+\startsetups apply:flush
+\relax
+ \ifcase\MMLapplydepth
+ \ifconditional\somepostponedMMLactions
+ \postponedMMLactions
+ \ifx\MMLpowerelement\empty\else
+ ^{\MMLcreset\MMLpowerelement\empty}
+ \global\let\MMLpowerelement\empty
+ \fi
+ \fi
+ \fi
+\stopsetups
+
+% reln
+
+\defineXMLnestedenvironmentsave [reln]
+ {\writestatus{XML}{MathML element "reln" is obsolete}}
+ {}
+
+% fn
+
+\startsetups mmc:fn:plusminus
+ \ifnum\XMLstacklevel>\plustwo
+ \MMLcreset
+ \left(\expandafter\flushXMLstackwith\expandafter\plustwo\expandafter{\XMLfnoperator}\right)
+ \else
+ \getXMLstackdata\plustwo
+ \fi
+\stopsetups
+
+\startsetups mmc:fn:minusplus
+ \directsetup{mmc:fn:plusminus}
+\stopsetups
+
+\defineXMLnested
+ [fn]
+ {\directsetup{mmc:fn:start}}
+ {\directsetup{mmc:fn:stop}}
+
+\startsetups mmc:fn:apply
+ \begingroup
+ \startsavingXMLelements
+ \rawXMLstacktext\plusone % still on stack, no check, just fn content
+ \stopsavingXMLelements
+ \doifelse {\getXMLstackname\plusone} {ci} {
+ \flattenXMLcontent{\getXMLstackdata\plusone}
+ \doifsetupselse{mmc:fn:\flattenedXMLcontent} {
+ \global\defXMLstackdata\XMLfnoperator\plusone
+ \expanded{\endgroup\noexpand\directsetup{mmc:fn:\flattenedXMLcontent}}
+ } {
+ \endgroup
+ \MMLcreset
+ \getXMLstackdata\plusone
+ \ifnum\XMLstacklevel>\plusone
+ \getXMLentity{NegThinSpace}
+ \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)
+ \fi
+ }
+ } {
+ \endgroup
+ \MMLcreset
+ \getXMLstackdata\plusone
+ }
+\stopsetups
+
+\startsetups mmc:fn:start
+ \ifnum\XMLstacklevel>\plustwo
+ \def\MMCfnleft {\left(}
+ \def\MMCfnright{\right)}
+ \else
+ \let\MMCfnleft \relax
+ \let\MMCfnright\relax
+ \fi
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:fn:stop
+ \stopsavingXMLelements
+ \doifelse {\getXMLstackname\plusone} {ci} {
+ \flattenXMLcontent{\getXMLstackdata\plusone}
+ \doifsetupselse{mmc:fn:\flattenedXMLcontent} {
+ \global\defXMLstackdata\XMLfnoperator\plusone
+ \directsetup{mmc:fn:\flattenedXMLcontent}
+ } {
+ \MMLcreset
+ \getXMLstackdata\plusone
+ }
+ \endgroup
+ } {
+ \doifelse {\getXMLstackname\plusone} {apply} {
+ \doifelseMMCfunctioninapply \plusone {plus,minus} {
+ \left(
+ \getXMLstackdata\plusone
+ \right)
+ } {
+ \getXMLstackdata\plusone
+ }
+ \endgroup
+ \ifnum\XMLstacklevel>\plusone
+ \left(
+ \getXMLstackdata\plustwo
+ \right)
+ \fi
+ } {
+ \MMLcreset
+ \getXMLentity{NegThinSpace}
+ \MMCfnleft
+ \ifnum\XMLstacklevel=\plustwo\MMLccomma\fi
+ \flushXMLstackwith\plustwo\MMLccomma
+ \MMCfnright
+ \endgroup
+ }
+ }
+\stopsetups
+
+% c*
+
+\defineXMLargument [ci] [type=] {\XMLval{mmc:ci}{\XMLop{type}} {\firstofoneargument}}
+\defineXMLargument [cn] [type=,base=] {\XMLval{mmc:cn}{\XMLop{type}} {\firstofoneargument}}
+\defineXMLargument [csymbol] [encoding=text] {\XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}}
+
+%D The next definition provide a kind of plug-in mechanism (see
+%D the open math extension module).
+
+\defineXMLsingular
+ [csymbol]
+ [encoding=text,
+ definitionURL=]
+ {\doifsomething{\XMLop{definitionURL}}{\directsetup{mmc:csymbol:apply}}}
+
+\startsetups mmc:csymbol:apply
+ \begingroup
+ \startsavingXMLelements
+ \rawXMLstacktext\plusone % still on stack, no check, just attr test
+ \stopsavingXMLelements
+ % http://www.publishers.com/SomeName
+ \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL
+ \doifsetupselse{mmc:csymbol:} {\mmcSymbolURL} {
+ \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\mmcSymbolURL}}
+ } {
+ % SomeName (fallback)
+ \splitfilename{\XMLpar{csymbol}{definitionURL}{}}
+ \doifsetupselse{mmc:csymbol:\splitoffbase} {
+ \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\splitoffbase}}
+ } {
+ \endgroup
+ \XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}
+ }
+ }
+\stopsetups
+
+%D Alternative b will convert periods into comma's:
+%D
+%D \startbuffer
+%D \startXMLdata
+%D <imath><apply><cn>1.23</cn></apply></imath>
+%D <dmath><apply><cn>1.23</cn></apply></dmath>
+%D \stopXMLdata
+%D
+%D \type{\setupMMLappearance[cn] [alternative=b]}
+%D
+%D \startXMLdata
+%D <imath><apply><cn>1.23</cn></apply></imath>
+%D <dmath><apply><cn>1.23</cn></apply></dmath>
+%D \stopXMLdata
+%D \stopbuffer
+%D
+%D \start \typebuffer \getbuffer \stop
+
+\setupMMLappearance[cn] [\c!alternative=\v!a]
+
+\defineXMLargument[cn][type=,base=]{\MMLdocn}
+
+\def\MMLdocn#1%
+ {\begingroup
+ \doif\@@MMLcnalternative\v!b{\redefinemathcharacter [.][ord][mi]["3B]\relax}%
+ \XMLval{mmc:cn}{\XMLop{type}}{\firstofoneargument}{#1}%
+ \endgroup}
+
+\defineXMLsingular [sep] {\MMLcsep} \def\MMLcsep{\,}
+
+\setupMMLappearance[polar] [\c!alternative=\v!a] % a|b|c
+\setupMMLappearance[float] [\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[enotation][\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[base] [\c!symbol=\v!numbers] % digits|characters|text|no
+
+\mapXMLvalue {mmc:ci} {set} {\MMLcCIset}
+\mapXMLvalue {mmc:ci} {vector} {\MMLcCIvector}
+\mapXMLvalue {mmc:ci} {matrix} {\MMLcCImatrix}
+\mapXMLvalue {mmc:ci} {function} {\MMLcCIfunction}
+\mapXMLvalue {mmc:ci} {complex-cartesian} {\MMLccartesian}
+\mapXMLvalue {mmc:ci} {complex} {\MMLccartesian}
+\mapXMLvalue {mmc:ci} {complex-polar} {\MMLcpolar}
+\mapXMLvalue {mmc:ci} {polar} {\MMLcpolar}
+\mapXMLvalue {mmc:ci} {fn} {\MMLcCIfunction}
+
+\mapXMLvalue {mmc:cn} {integer} {\MMLcCNinteger}
+\mapXMLvalue {mmc:cn} {logical} {\MMLcCNlogical}
+\mapXMLvalue {mmc:cn} {rational} {\MMLcCNrational}
+\mapXMLvalue {mmc:cn} {complex-cartesian} {\MMLccartesian}
+\mapXMLvalue {mmc:cn} {complex} {\MMLccartesian}
+\mapXMLvalue {mmc:cn} {complex-polar} {\MMLcpolar}
+\mapXMLvalue {mmc:cn} {polar} {\MMLcpolar}
+\mapXMLvalue {mmc:cn} {e-notation} {\MMLcenotation} % new
+\mapXMLvalue {mmc:cn} {float} {\MMLcfloat} % obsolete
+\mapXMLvalue {mmc:cn} {real} {\MMLcfloat}
+
+\mapXMLvalue {mmc:cs} {text} {\MMLcCStext}
+
+\def\MMLcpolar#1%
+ {\doifdefinedelse{MMLcdopolar\@@MMLpolaralternative}
+ {\getvalue{MMLcdopolar\@@MMLpolaralternative}{#1}}
+ {#1}}
+
+\def\MMLcdopolara#1%
+ {\def\MMLcsep{\MMLseparator,}\getXMLentity{polar}\left(#1\right)}
+
+\def\MMLcdopolarb#1%
+ {\def\MMLcsep##1\empty
+ {\getXMLentity{exponentiale}^{##1\mskip2mu\getXMLentity{imaginaryi}}}
+ #1\empty}
+
+\def\MMLcdopolarc#1%
+ {\def\MMLcsep##1\empty
+ {\getXMLentity{exp}\left(##1\mskip2mu\getXMLentity{imaginaryi}\right)}%
+ #1\empty}
+
+\def\MMLccartesian#1%
+ {\def\MMLcsep{+}#1\getXMLentity{imaginaryi}}
+
+% float will be obsolete, and is replace by e-notation
+
+\def\MMLcfloat#1%
+ {\doifelse\@@MMLfloatsymbol\v!no
+% {{\MMLrm#1}}% make sure that e shows up ok
+ {\mfunction{#1}}% make sure that e shows up ok
+ {% we should ignore \entities !
+ \beforesplitstring#1\at e\to\first
+ \aftersplitstring #1\at e\to\last
+ \ifx\first\empty #1\else
+ \ifx\last \empty #1\else
+ \first
+ \doifelse\@@MMLfloatsymbol{dot}\cdot\times
+ 10^{\last}%
+ \fi\fi}}
+
+% we now have:
+
+\def\MMLcenotation#1%
+ {\doifelse\@@MMLenotationsymbol\v!no
+% {\def\MMLcsep {\unskip{\MMLrm e}\ignorespaces}}
+ {\def\MMLcsep {\unskip\mfunction{e}\ignorespaces}}
+ {\def\MMLcsep##1\empty{\doifelse\@@MMLenotationsymbol{dot}\cdot\times10^{##1}}}%
+ #1\empty}
+
+\def\MMLcCIset#1%
+ {{\bbd#1}}
+
+\def\widevec#1%
+ {\vbox{\mathsurround\zeropoint\ialign{##\crcr
+ \rightarrowfill\crcr\noalign{\nointerlineskip}%
+ $\hfil\displaystyle{#1}\hfil$\crcr}}}
+
+\def\MMLcCIvector#1%
+ {\widevec{#1}}
+
+\def\MMLcCImatrix#1%
+ {{\bi#1}}
+
+\def\MMLcCIfunction#1%
+ {#1\getXMLentity{NegThinSpace}}
+
+\def\MMLcCNinteger#1%
+ {\doifXMLparelse{cn}{base}
+ {\def\MMLcCNbase{\XMLpar{cn}{base}{}}%
+ \doifelse\@@MMLbasesymbol\v!no
+ {\MMLcCNbasedata{#1}}
+% {\MMLcCNbasedata{#1}_{\hbox{$\MMLrm\scriptscriptstyle
+ {\MMLcCNbasedata{#1}_{\mfunction{%
+ \processaction
+ [\@@MMLbasesymbol]
+ [\v!characters=>\MMLcCNbasestring BODH,
+ \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
+% \s!unknown=>\MMLcCNbase]$}}}}
+ \s!unknown=>\MMLcCNbase]}}}}
+ {#1}}
+
+\def\MMLcCNbasedata#1%
+% {\ifnum\MMLcCNbase>10{\MMLrm#1}\else#1\fi}
+ {\ifnum\MMLcCNbase>10\mfunction{#1}\else#1\fi}
+
+\def\MMLcCNbasestring#1#2#3#4%
+ {\ifnum\MMLcCNbase= 2 #1\else
+ \ifnum\MMLcCNbase= 8 #2\else
+ \ifnum\MMLcCNbase=10 #3\else
+ \ifnum\MMLcCNbase=16 #4\else
+ \MMLcCNbase \fi\fi\fi\fi}
+
+\def\MMLcCNlogical#1%
+% {{\MMLrm#1}}
+ {\mfunction{#1}}
+
+\bgroup \catcode`\<=\active
+
+ % quick and dirty, best track the stack (todo)
+
+ \gdef\MMLcCNrational#1%
+ {\ConvertConstantAfter\doifinstringelse{sep}{#1}
+ {\doMMLcCNrational#1\empty}
+ {#1}}
+
+ \gdef\doMMLcCNrational#1<sep#2>#3\empty
+ {\hbox{$\frac{#1}{#3}$}}
+
+\egroup
+
+\def\MMLcCStext#1%
+% {{\MMLrm#1}}
+ {\mfunction{#1}}
+
+% interval
+
+\defineXMLnested [interval]
+ [closure=closed]
+ {\directsetup{mmc:interval:start}}
+ {\directsetup{mmc:interval:stop}}
+
+\startsetups mmc:interval:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:interval:stop
+ \stopsavingXMLelements
+ \XMLval{mmc:int}{\XMLpar{interval}{closure}{closed}}{error}
+ \endgroup
+\stopsetups
+
+\startsetups mmc:interval:fetch
+ \defineXMLnested [interval]
+ [closure=closed]
+ {\directsetup{mmc:interval:fetch:start}}
+ {\directsetup{mmc:interval:fetch:stop}}
+\stopsetups
+
+\startsetups mmc:interval:fetch:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:interval:fetch:stop
+ \stopsavingXMLelements
+ \globallet\MMCintervalfrom\empty
+ \globallet\MMCintervalto \empty
+ \ifcase\XMLstacklevel
+ \or
+ \xdef\MMCintervalfrom{\getXMLstackdata\plusone}
+ \or
+ \xdef\MMCintervalfrom{\getXMLstackdata\plusone}
+ \xdef\MMCintervalto {\getXMLstackdata\plustwo}
+ \fi
+ \endgroup
+\stopsetups
+
+\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}]
+
+\mapXMLvalue {mmc:int} {closed}
+ {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]}
+
+\mapXMLvalue {mmc:int} {open-closed}
+ {\doifelse\@@MMLintervalalternative\v!b
+ {\left<\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]}
+ {\left(\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right]}}
+
+\mapXMLvalue {mmc:int} {closed-open}
+ {\doifelse\@@MMLintervalalternative\v!b
+ {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right>}
+ {\left[\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right)}}
+
+\mapXMLvalue {mmc:int} {open}
+ {\doifelse\@@MMLintervalalternative\v!b
+ {\left<\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right>}
+ {\left(\getXMLstackdata\plusone\MMLseparator\@@MMLintervalseparator\getXMLstackdata\plustwo\right)}}
+
+% inverse
+
+\defineXMLcommand [inverse] {\directsetup{mmc:inverse}}
+
+\startsetups mmc:inverse
+ \ifnum\XMLstacklevel>\plustwo
+ \getXMLentity{\getXMLstackname\plustwo}^{-1}
+ \left[\getXMLstackdata\plusthree\right]
+ \else
+ \xdef\MMLpowerelement{-1}
+ \expanded{\postponeMMLactions{\rawXMLstackdata\plustwo}}
+ \eraseXMLdataonstack\plustwo
+ \fi
+\stopsetups
+
+% condition
+
+\defineXMLnested
+ [condition]
+ {\directsetup{mmc:condition:start}}
+ {\directsetup{mmc:condition:stop}}
+
+\startsetups mmc:condition:start
+% \XMLdoifonstackelse{bvar} {
+% \XMLfirstnamed{bvar}\mid
+% } { }
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:condition:stop
+ \stopsavingXMLelements
+ \flushXMLstackfrom\plusone
+ \endgroup
+\stopsetups
+
+% declare
+
+\setupMMLappearance[declare][\c!state=\v!start]
+
+\defineXMLnested
+ [declare]
+ {\directsetup{mmc:declare:start}}
+ {\directsetup{mmc:declare:stop}}
+
+\startsetups mmc:declare:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:declare:stop
+ \stopsavingXMLelements
+ \doif\@@MMLdeclarestate\v!start {
+ \getXMLentity{declare}\getXMLstackdata\plusone
+ \ifnum\XMLstacklevel>\plusone
+ \getXMLentity{ThickSpace}
+ \getXMLentity{as}
+ \getXMLentity{ThickSpace}
+ \fi
+ \getXMLstackdata\plustwo
+ }
+ \endgroup
+\stopsetups
+
+% lambda
+
+\setupMMLappearance[lambda][\c!alternative=b]
+
+\defineXMLnested
+ [lambda]
+ {\directsetup{mmc:lambda:start}}
+ {\directsetup{mmc:lambda:stop}}
+
+\startsetups mmc:lambda:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:lambda:stop
+ \stopsavingXMLelements
+ \doifelse\@@MMLlambdaalternative\v!a {
+ \getXMLentity{lambda}(\flushXMLstackwith\plusone{\MMLseparator,})
+ } {
+ \countXMLnamedstack{bvar}
+ \ifnum\scratchcounter>\plusone
+ \left(\flushXMLnamedstackwith\plusone{bvar}{\MMLseparator,}\right)
+ \else
+ \XMLfirstnamed{bvar}
+ \fi
+ \getXMLentity{mapsto}
+ \MMLcreset
+ \XMLfirstnamed{apply,reln,ci,cn}
+ }
+ \endgroup
+\stopsetups
+
+\startsetups mmc:lambda:simple
+ \defineXMLnested
+ [lambda]
+ {\directsetup{mmc:lambda:simple:start}}
+ {\directsetup{mmc:lambda:simple:stop}}
+\stopsetups
+
+\startsetups mmc:lambda:simple:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:lambda:simple:stop
+ \stopsavingXMLelements
+ \MMLcreset % new
+ \XMLfirstnamed{apply}
+ \endgroup
+\stopsetups
+
+% compose
+
+\defineXMLcommand [compose] {\directsetup{mmc:compose}}
+
+\startsetups mmc:compose
+ \begingroup
+ \MMLcreset
+ \let\MMLcCIfunction\firstofoneargument % brrr
+ \doifelseMMCfunction {
+ \left(\flushXMLstackwith\plustwo\circ\right)
+ } {
+ \flushXMLstackwith\plustwo\circ
+ }
+ \endgroup
+\stopsetups
+
+\defineXMLcommand [image] {\directsetup{mmc:image}}
+
+\startsetups mmc:image
+ \getXMLentity{image}
+ \left(
+ \begingroup
+ \startlocalsetups [mmc:function]
+ \getXMLentity\currentXMLelement
+ \stoplocalsetups
+ \getXMLstackdata\plustwo
+ \endgroup
+ \right)
+\stopsetups
+
+\setupMMLappearance[piece][\c!separator=]
+
+\def\setMMLcPIECEseparator
+ {\processaction
+ [\@@MMLpieceseparator]
+ [ \v!yes=>\def\theMMLpieceseparator{,\@col@amp@},
+ \v!no=>\let\theMMLpieceseparator\@col@amp@,
+ \s!default=>\let\theMMLpieceseparator\@col@amp@,
+ \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\@@MMLpieceseparator}\,\,}]}
+
+\defineXMLargument[piecewise] {\cases}
+
+\defineXMLnested
+ [piece]
+ {\directsetup{mmc:piece:start}}
+ {\directsetup{mmc:piece:stop}}
+
+\defineXMLenvironmentsave
+ [otherwise]
+ {}
+ {\directsetup{mmc:otherwise}}
+
+\startsetups mmc:piece:start
+ \startsavingXMLelements
+ \setMMLcPIECEseparator
+\stopsetups
+
+\startsetups mmc:piece:stop
+ \stopsavingXMLelements
+ \edef\ascii{\getXMLstackdata\plusone}
+ \@EA\XMLRtoks\@EA{\ascii\theMMLpieceseparator}
+ \edef\ascii{\getXMLstackdata\plustwo}
+ \@EA\appendtoks\@EA\mathematics\@EA{\ascii}\to\XMLRtoks
+ \the\XMLRtoks\crcr
+\stopsetups
+
+\startsetups mmc:otherwise
+ \XMLflush{otherwise}\MMLcPIECEseparator\@col@amp@\mathematics{\getXMLentity{otherwise}}\crcr
+\stopsetups
+
+\defineXMLcommand [quotient] {\directsetup{mmc:quotient}}
+
+\startsetups mmc:quotient
+ \lfloor\getXMLstackdata\plustwo/\getXMLstackdata\plusthree\rfloor
+\stopsetups
+
+\defineXMLcommand [factorial] {\getXMLstackdata\plustwo !}
+
+\defineXMLcommand [divide] [\MMLargumentprefix] [] {\directsetup{mmc:divide}} % brr not nested
+
+\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a]
+
+\startsetups mmc:divide
+ \startusingMMLarguments
+ \increment\MMLcDIVIDElevel
+ \doifelse \@@MMLdividealternative\v!b {
+ \getXMLstackdata\plustwo/\getXMLstackdata\plusthree
+ } {
+ \ifnum\MMLcDIVIDElevel>\@@MMLdividelevel\space
+ \getXMLstackdata\plustwo/\getXMLstackdata\plusthree
+ \else
+ \MMLcreset
+ \frac{\MMLcreset\getXMLstackdata\plustwo}{\MMLcreset\getXMLstackdata\plusthree}%
+ \fi
+ }
+ \decrement\MMLcDIVIDElevel
+ \stopusingMMLarguments
+\stopsetups
+
+% min max
+
+\defineXMLcommand [min] {\min\directsetup{mmc:minmax}}
+\defineXMLcommand [max] {\max\directsetup{mmc:minmax}}
+
+\startsetups mmc:minmax
+ \doifelse{\getXMLstackdata\plustwo}{bvar} {
+ {}_{\getXMLstackdata\plustwo}
+ \left\{\flushXMLstackwith\plusthree{\MMLseparator,}\right\}
+ } {
+ \left\{\flushXMLstackwith\plustwo {\MMLseparator,}\right\}
+ }
+\stopsetups
+
+% minus plus
+
+\defineXMLcommand [minus] {\directsetup{mmc:minus}}
+\defineXMLcommand [plus] [\MMLargumentprefix] [] {\directsetup{mmc:plus}}
+
+\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4
+\setupMMLappearance [sign] [\c!reduction=\v!yes]
+
+\startsetups mmc:minus
+ \doif \@@MMLsignreduction \v!yes {
+ \setMMLcreset{fn,\MMLcfunctionlist}
+ }
+ \ifcase\XMLstacklevel
+ \or
+ % self
+ \or
+ -\getXMLstackdata\plustwo
+ \else
+ \flushXMLstackwith\plustwo-
+ \fi
+\stopsetups
+
+\startsetups mmc:plus
+ \startusingMMLarguments
+ \doifelse \@@MMLsignreduction \v!yes {
+ \setMMLcreset{fn,plus,minus,\MMLcfunctionlist,\MMLcconstructlist}% was plus/, minus/
+ \doifelse{\getXMLstackname\plustwo} {apply} {
+ % branch needed, else (a-b) + (c-d) goes wrong
+ % reset check in case of (-x) + 37
+ \begingroup
+ \dodoifelseMMCfunctioninapply \plustwo {minus} {
+ \ifnum\XMLstacklevel>\plustwo
+ \endgroup
+ \else
+ \endgroup
+ \MMLcreset
+ \fi
+ } {
+ \endgroup
+ }
+ \doifelse \@@MMLplusalternative \v!b {
+ \getXMLstackdata\plustwo \,
+ } {
+ \flushXMLstackwith\plustwo +
+ }
+
+ } {
+ \flushXMLstackwith\plustwo {
+ \doifelse {\getXMLstackname\recurselevel} {apply} {
+ \begingroup
+ \dodoifelseMMCfunctioninapply \recurselevel {minus} {
+ \ifnum\XMLstacklevel>\plustwo +\fi
+ } {
+ \doifelse \@@MMLplusalternative \v!b {
+ \, % maybe 2 1/3
+ } {
+ +
+ }
+ }
+ \endgroup
+ \MMLcreset
+ } {
+ +
+ }
+ }
+ }
+ } {
+ \ifcase\XMLstacklevel
+ \or
+ % self
+ \or
+ +\getXMLstackdata\plustwo
+ \else
+ \flushXMLstackwith\plustwo+
+ \fi
+ }
+ \stopusingMMLarguments
+\stopsetups
+
+% power
+
+\defineXMLcommand [power] {\directsetup{mmc:power}}
+
+\setupMMLappearance[power][\c!reduction=\v!yes]
+
+\let\MMLpowerelement\empty
+
+\startsetups mmc:power
+ \doifelse {\getXMLstackname\plustwo} {apply} {
+ \doifelse\@@MMLpowerreduction\v!yes {
+ \doifelseMMCfunctioninapply \plustwo \MMLcfunctionlist {
+ \xdef\MMLpowerelement{\getXMLstackdata\plusthree}% postpone
+ \MMLcreset\getXMLstackdata\plustwo
+ } {
+ \left(\MMLcreset\getXMLstackdata\plustwo\right)^{\MMLcreset\getXMLstackdata\plusthree}
+ }
+ } {
+ \left(\MMLcreset\getXMLstackdata\plustwo\right)^{\MMLcreset\getXMLstackdata\plusthree}
+ }
+ } {
+ \getXMLstackdata\plustwo^{\MMLcreset\getXMLstackdata\plusthree}
+ }
+\stopsetups
+
+% rem
+
+\defineXMLcommand [rem] {\flushXMLstackwith\plustwo{\getXMLentity{mod}}}
+
+\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn
+
+\defineXMLcommand [times] [\MMLargumentprefix] [] {\directsetup{mmc:times}}
+
+\startsetups mmc:times
+ \startusingMMLarguments
+ \setMMLcreset{\MMLcfunctionlist,\MMLcconstructlist}%
+ \doifelse\@@MMLtimesauto\v!no {
+ \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ } {
+ \countXMLnamedstack {cn}
+ \ifnum\scratchcounter>\plusone
+ \doifinsetelse\@@MMLtimessymbol{\v!yes,\v!no} {
+ \let\@@MMLtimes@@symbol\v!yes
+ } {
+ \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ }
+ \else
+ \let\@@MMLtimes@@symbol\@@MMLtimessymbol
+ \fi
+ }
+ \doifelse\@@MMLtimes@@symbol\v!yes {
+ \flushXMLstackwith\plustwo\times
+ } {
+ \doifelse\@@MMLtimes@@symbol{dot} {
+ \flushXMLstackwith\plustwo\cdot
+ } {
+ \doifelse\@@MMLtimes@@symbol{times} {
+ \flushXMLstackwith\plustwo\times
+ } {
+ \flushXMLstackwith\plustwo\empty
+ }
+ }
+ }
+ \stopusingMMLarguments
+\stopsetups
+
+\defineXMLcommand [root] {\directsetup{mmc:root}}
+
+\setupMMLappearance[root][\c!symbol=\v!yes]
+
+\startsetups mmc:root
+ \XMLdoifonstackelse {degree} {
+ \root
+ \doifnot\@@MMLrootsymbol\v!no{\MMLcreset\XMLfirstnamed{degree}}
+ \of
+ } {
+ \sqrt
+ }
+ {\MMLcreset\XMLfirstnamed{apply,reln,ci,cn}}
+\stopsetups
+
+% gcd
+
+\defineXMLcommand [gcd] {\gcd\left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)}
+
+% and or xor implies
+
+\defineXMLcommand [and] {\flushXMLstackwith\plustwo{\getXMLentity{and}}}
+\defineXMLcommand [or] {\flushXMLstackwith\plustwo{\getXMLentity{or}}}
+\defineXMLcommand [xor] {\flushXMLstackwith\plustwo{\getXMLentity{xor}}}
+\defineXMLcommand [implies] {\flushXMLstackwith\plustwo{\getXMLentity{implies}}}
+
+% not
+
+\defineXMLcommand [not] {\getXMLentity{not}\getXMLstackdata\plustwo}
+
+% forall exists
+
+\defineXMLcommand [forall] {\directsetup{mmc:forall}}
+\defineXMLcommand [exists] {\directsetup{mmc:exists}}
+
+%D We need to shift left below rotated A.
+
+\startsetups mmc:forall
+ \getXMLentity{forall}
+ \getXMLentity{NegThinSpace}
+ \directsetup{mmc:forall-exists}
+\stopsetups
+
+\startsetups mmc:exists
+ \getXMLentity{exists}
+ \directsetup{mmc:forall-exists}
+\stopsetups
+
+\startsetups mmc:forall-exists
+ _{\flushXMLnamedstackwith\plustwo{bvar}{\MMLseparator,}}
+ \XMLdoifonstackelse {condition} {
+ \getXMLentity{ThickSpace}
+ \begingroup
+ \XMLfirstnamed{condition}
+ \endgroup
+ \countXMLnamedstack {apply,reln,ci,cn}
+ \ifcase\scratchcounter
+ \or
+ % == snelle volgende
+ \left\vert \MMLcreset
+ \getXMLentity{MediumSpace}
+ \flushXMLnamedstackwith\plustwo{apply,reln,ci,cn}\empty
+ \right.
+ \else
+ % special case
+ % \defineXMLignore[condition]
+ \collectXMLnamedstack{apply,reln,ci,cn}{\hfill\crcr}
+ \left\vert
+ \matrix{\the\XMLRtoks}
+ \right.
+ \fi
+ } {
+ :\XMLfirstnamed{apply,reln,ci,cn}
+ }
+\stopsetups
+
+\defineXMLcommand [abs] {\left\vert \MMLcreset \flushXMLstackfrom\plustwo \right\vert}
+\defineXMLcommand [conjugate] {{\overline{\MMLcreset \flushXMLstackfrom\plustwo}}} % watch extra {}
+\defineXMLcommand [arg] {\getXMLentity{arg} \left(\MMLcreset\flushXMLstackfrom\plustwo\right)}
+\defineXMLcommand [real] {\getXMLentity{real} \left(\MMLcreset\flushXMLstackfrom\plustwo\right)}
+\defineXMLcommand [imaginary] {\getXMLentity{imaginary}\left(\MMLcreset\flushXMLstackfrom\plustwo\right)}
+\defineXMLcommand [lcm] {\getXMLentity{lcm} \left(\flushXMLstackwith\plustwo{\MMLseparator,}\right)}
+\defineXMLcommand [floor] {\getXMLentity{lfloor} \flushXMLstackfrom\plustwo \getXMLentity{rfloor}}
+\defineXMLcommand [ceiling] {\getXMLentity{lceiling} \flushXMLstackfrom\plustwo \getXMLentity{rceiling}}
+
+% relations
+
+\defineXMLcommand [eq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation=}
+\defineXMLcommand [neq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\neq}
+\defineXMLcommand [gt] [\MMLargumentprefix] [\c!align=] {\MMLcrelation>}
+\defineXMLcommand [lt] [\MMLargumentprefix] [\c!align=] {\MMLcrelation<}
+\defineXMLcommand [geq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\geq}
+\defineXMLcommand [leq] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\leq}
+\defineXMLcommand [equivalent] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\equiv}
+\defineXMLcommand [approx] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\approx}
+\defineXMLcommand [factorof] [\MMLargumentprefix] [\c!align=] {\MMLcrelation\mid}
+
+\setupMMLappearance[relation][\c!align=\v!no]
+
+\def\MMLcrelation
+ {\startusingMMLarguments
+ \MMLcreset
+ \edef\@@MMLrelationalign{\executeifdefined{\MMLargumentprefix\c!align}\@@MMLrelationalign}%
+ \processaction
+ [\@@MMLrelationalign]
+ [\v!last=>\let\next\lastMMLcrelation ,
+ \v!first=>\let\next\firstMMLcrelation,
+ \v!yes=>\let\next\leftMMLcrelation ,
+ \v!left=>\let\next\leftMMLcrelation ,
+ \v!right=>\let\next\rightMMLcrelation,
+ \s!default=>\let\next\noMMLcrelation ,
+ \s!unknown=>\let\next\noMMLcrelation ]
+ \next}
+
+\def\noMMLcrelation#1%
+ {\flushXMLstackwith\plustwo{#1}
+ \stopusingMMLarguments}
+
+\def\lastMMLcrelation#1% weird, probably bugged
+ {\XMLRtoks\emptytoks
+ \dostepwiserecurse\plustwo\XMLstacklevel\plusone
+ {\appendetoks\noexpand\getXMLstackdata{\recurselevel}\to\XMLRtoks
+ \ifnum\recurselevel<\numexpr\XMLstacklevel-1\relax
+ \appendtoks\@col@amp@#1\crcr\to\XMLRtoks
+ \else\ifnum\recurselevel=\numexpr\XMLstacklevel-1\relax
+ \appendtoks\@col@amp@#1\to\XMLRtoks
+ \fi\fi}%
+ \eqalign{\the\XMLRtoks\crcr}%
+ \stopusingMMLarguments}
+
+\def\firstMMLcrelation#1%
+ {\collectXMLstackrows\plusthree{\crcr\@col@amp@#1}%
+ \eqalign{\getXMLstackdata\plustwo\@col@amp@#1\the\XMLRtoks}%
+ \stopusingMMLarguments}
+
+\def\leftMMLcrelation#1%
+ {\collectXMLstackrows\plustwo{\@col@amp@#1\crcr}%
+ \eqalign{\the\XMLRtoks}%
+ \stopusingMMLarguments}
+
+\def\rightMMLcrelation#1%
+ {\collectXMLstackrows\plustwo{\crcr#1{}\@col@amp@}%
+ \eqalign{\@col@amp@\the\XMLRtoks\crcr}%
+ \stopusingMMLarguments}
+
+\defineXMLcommand [becomes] {\MMLcrelation{:=}}
+
+\addtocommalist{becomes/}\MMLcmainresetlist
+
+% calculus and vector calculus
+
+\setupMMLappearance[int][\c!location=\v!top]
+
+\def\doMMLlimits#1%
+ {\doifelsevalue{@@MML#1\c!location}\v!top\limits\nolimits}
+
+\defineXMLnested
+ [domainofapplication]
+ {\directsetup{mmc:domainofapplication:start}}
+ {\directsetup{mmc:domainofapplication:stop}}
+
+\startsetups mmc:domainofapplication:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:domainofapplication:stop
+ \stopsavingXMLelements
+% \MMLcreset
+ \flushXMLstackfrom\plusone
+ \endgroup
+\stopsetups
+
+\defineXMLcommand [int] {\directsetup{mmc:int}}
+
+\startsetups mmc:int
+ \MMLcreset
+ \XMLdoifonstackelse{domainofapplication} {
+ \int\doMMLlimits{int}_{\XMLfirstnamed{domainofapplication}}\relax
+ } {
+ \XMLdoifonstackelse{condition} {
+ \int\doMMLlimits{int}_{\XMLfirstnamed{condition}}\relax
+ } {
+ \XMLdoifonstackelse{lowlimit} {
+ \int\doMMLlimits{int}
+ _{\XMLfirstnamed{lowlimit}}
+ ^{\XMLfirstnamed{uplimit}}
+ } {
+ % funny, why do we have lowlimit/uplimit then
+ \XMLdoifonstackelse{interval} {
+ \begingroup
+ \startlocalsetups mmc:interval:start %
+ \begingroup
+ \startsavingXMLelements
+ \stoplocalsetups
+ \startlocalsetups mmc:interval:stop %
+ \stopsavingXMLelements
+ \xdef\MMLfirstelement {\getXMLstackdata\plusone}
+ \xdef\MMLsecondelement{\getXMLstackdata\plustwo}
+ \endgroup
+ \stoplocalsetups
+ \globallet\MMLfirstelement \empty
+ \globallet\MMLsecondelement\empty
+ \XMLfirstnamed{interval}
+ \endgroup
+ \int\doMMLlimits{int}
+ _{\MMLfirstelement}
+ ^{\MMLsecondelement}
+ } {
+ \int
+ }
+ }
+ }
+ }
+ \MMLcreset
+ \XMLdoifonstackelse{apply} {
+ \doifelseMMCfunction {
+ \XMLfirstnamed{apply}
+ } {
+ % if there are too many () now, we need to be more clever
+ \left(\XMLfirstnamed{apply}\right)
+ }
+ } {
+ \XMLfirstnamed{ci}
+ }
+ \XMLdoifonstackelse{bvar} {
+ \,% \getXMLentity{ThinSpace}%
+% {\MMLrm\getXMLentity{mathematicald}}
+ \mfunction{\getXMLentity{mathematicald}}
+ \XMLfirstnamed{bvar}
+ } {
+ % nothing
+ }
+\stopsetups
+
+\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
+
+\defineXMLcommand [diff] {\directsetup{mmc:diff}}
+\defineXMLcommand [partialdiff] {\directsetup{mmc:partialdiff}}
+
+% \setupMMLappearance[diff][alternative=b]
+%
+% \startXMLdata
+% <math><apply><apply><diff/><bvar><ci>x</ci></bvar><ci>f</ci></apply><ci>a</ci></apply></math>
+% <math><apply><apply><diff/><bvar><ci>x</ci></bvar><degree>2</degree><ci>f</ci></apply><ci>a</ci></apply></math>
+% \stopXMLdata
+
+% d^y/dx^2
+%
+% \startXMLdata
+% <math><apply><diff/>
+% <bvar><ci>x</ci><cn type="integer">2</cn></bvar>
+% <lambda><bvar><ci>x</ci></bvar><ci>y</ci></lambda>
+% </apply></math>
+% \stopXMLdata
+
+\startsetups mmc:diff
+ \MMLcreset
+ \doifelse\@@MMLdiffalternative\v!a {
+ \XMLdoifonstackelse{lambda} {
+ % a special case (mathadore/openmath)
+ \begingroup
+ \defineXMLsave[ci]
+ \defineXMLsave[cn]
+ \defineXMLprocess[lambda]
+ \defineXMLprocess[bvar]
+ \frac {
+ d^{\XMLfirstnamed{bvar}\XMLflush{cn}}{\XMLfirstnamed{lambda}\XMLflush{ci}}
+ } {
+ d{\XMLfirstnamed{bvar}\XMLflush{ci}}^{\XMLfirstnamed{bvar}\XMLflush{cn}}
+ }
+ \endgroup
+ } {
+ \XMLdoifonstackelse{bvar} {
+ \frac {
+ \XMLdoifonstackelse{degree} {
+ \collectXMLnamedstack{degree}\empty
+ } {
+ \collectXMLnamedstacknamed{bvar}{degree}+
+ }
+ \mfunction{\getXMLentity{mathematicald}}
+ ^{\the\XMLRtoks}
+ \doif\@@MMLdifflocation\v!top {
+ \XMLdoifonstackelse{ci} {
+ \XMLfirstnamed{ci}
+ } {
+ \MMLcreset\XMLfirstnamed{apply}
+ }
+ }
+ } {
+ \mfunction{\getXMLentity{mathematicald}}
+ \begingroup
+ \defineXMLsave[degree]
+ \XMLfirstnamed{bvar}
+ \doifXMLdata{degree} {
+ ^{\XMLflush{degree}}
+ }
+ \endgroup
+ }
+ \doifnot\@@MMLdifflocation\v!top {
+ \left(\MMLcreset\XMLfirstnamed{apply,ci}\right)
+ }
+ } {
+ \flushXMLstackfrom\plustwo^\prime
+ }
+ }
+ } {
+ \MMLcreset
+ \XMLfirstnamed{apply,ci}
+ % there can be problems with nested diff's: ^^{} error
+ % so we add an empty group here
+ {}^
+ {
+ \XMLdoifonstackelse{degree} {
+ \defXMLfirstnamedtext\ascii{degree}
+ \dorecurse\ascii\prime
+ } {
+ \prime
+ }
+ }
+ }
+\stopsetups
+
+\startsetups mmc:partialdiff
+ \XMLdoifonstackelse{list} {
+ \getXMLentity{capitaldifferentiald}_{
+ \begingroup
+ \setfalse\MMLlistdelimiters
+ \XMLallnamed{list}
+ \endgroup
+ }
+ \XMLfirstnamed{apply,reln,ci,cn}
+ } {
+ \XMLdoifonstackelse{bvar} {
+ \frac {
+ \XMLdoifonstackelse{degree} {
+ \collectXMLnamedstack{degree}\empty
+ } {
+ \collectXMLnamedstacknamed{bvar}{degree}+
+ }
+ \getXMLentity{differentiald}^{\the\XMLRtoks}
+ % \let\MMLcDEGREE\gobbletwoarguments
+ % \doifelseMMCfunction\MMLcreset\donothing
+ \MMLcreset
+ \XMLfirstnamed{apply,reln,ci,cn}
+ } {
+ \defineXMLnested[bvar]
+ {\directsetup{mmc:bvar:diff:start}}
+ {\directsetup{mmc:bvar:diff:stop}}
+ \XMLfirstnamed{bvar}
+ }
+ } {
+ \XMLfirstnamed{apply,reln,ci,cn}
+ }
+ }
+\stopsetups
+
+\startsetups mmc:bvar:diff:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:bvar:diff:stop
+ \stopsavingXMLelements
+ \getXMLentity{differentiald}\XMLfirstnamed{apply,reln,ci,cn}
+ \XMLdoifonstackelse{degree} {
+ ^{\XMLfirstnamed{degree}}
+ } {
+ % nothing
+ }
+ \endgroup
+\stopsetups
+
+\def\subMMLcelement #1#2{_{#2}}
+\def\superMMLcelement#1#2{^{#2}}
+
+\defineXMLprocess [lowlimit]
+\defineXMLprocess [uplimit]
+\defineXMLprocess [bvar]
+\defineXMLprocess [degree]
+
+% option:
+%
+% \defineXMLentity [div] {\mathematics{\triangledown\times}}
+% \defineXMLentity [curl] {\mathematics{\triangledown .}}
+% \defineXMLentity [grad] {\mathematics{\triangledown }}
+
+\defineXMLcommand [divergence] {\getXMLentity{divergence}\directsetup{mmc:donamedfunction}}
+\defineXMLcommand [grad] {\getXMLentity {grad}\directsetup{mmc:donamedfunction}}
+\defineXMLcommand [curl] {\getXMLentity {curl}\directsetup{mmc:donamedfunction}}
+\defineXMLcommand [laplacian] {\getXMLentity {laplacian}\directsetup{mmc:donamedfunction}}
+
+\defineXMLcommand [ident] {\getXMLentity {identity}\directsetup{mmc:donamedfunction}}
+% \defineXMLcommand [domain] {\getXMLentity {domain}\directsetup{mmc:donamedfunction}}
+% \defineXMLcommand [codomain] {\getXMLentity {codomain}\directsetup{mmc:donamedfunction}}
+
+\defineXMLcommand[domain] {\directsetup{mmc:domain:action}}
+\defineXMLcommand[codomain]{\directsetup{mmc:codomain:action}}
+
+\setupMMLappearance[domain] [symbol=]
+\setupMMLappearance[codomain][symbol=]
+
+\startsetups mmc:domain:action
+ \doifelsenothing\@@MMLdomainsymbol {
+ \getXMLentity{domain}\directsetup{mmc:donamedfunction}
+ } {
+ \@@MMLdomainsymbol_{\flushXMLstackfrom\plustwo}
+ }
+\stopsetups
+\startsetups mmc:codomain:action
+ \doifelsenothing\@@MMLcodomainsymbol {
+ \getXMLentity{codomain}\directsetup{mmc:donamedfunction}
+ } {
+ \@@MMLcodomainsymbol_{\flushXMLstackfrom\plustwo}
+ }
+\stopsetups
+
+
+\startsetups mmc:donamedfunction
+% \left(
+% \begingroup
+ \MMLcreset\flushXMLstackfrom\plustwo
+% \endgroup
+% \right)
+\stopsetups
+
+% theory of sets
+
+\defineXMLnested [set]
+ {\setups{mmc:set:start}}
+ {\setups{mmc:set:stop}}
+
+\startsetups mmc:set:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:set:stop
+ \stopsavingXMLelements
+ \XMLdoifonstackelse{condition} {
+ \left\{\XMLfirstnamed{bvar}\,\middle\vert\,\XMLfirstnamed{condition}\right\}
+ } {
+ \left\{\flushXMLstackwith\plusone{\MMLseparator,}\right\}
+ }
+ \endgroup
+\stopsetups
+
+\defineXMLnested [list]
+ {\setups{mmc:list:start}}
+ {\setups{mmc:list:stop}}
+
+\settrue\MMLlistdelimiters
+
+\startsetups mmc:list:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:list:stop
+ \stopsavingXMLelements
+ \ifconditional\MMLlistdelimiters\left [\fi
+ \begingroup
+ \settrue\MMLlistdelimiters
+ \flushXMLstackwith\plusone{\MMLseparator,}
+ \endgroup
+ \ifconditional\MMLlistdelimiters\right]\fi
+ \endgroup
+\stopsetups
+
+\defineXMLcommand [union] {\MMLcset\cup}
+\defineXMLcommand [intersect] {\MMLcset\cap}
+\defineXMLcommand [in] {\MMLcset\in}
+\defineXMLcommand [notin] {\MMLcset{\not\in}}
+\defineXMLcommand [subset] {\MMLcset\subset}
+\defineXMLcommand [prsubset] {\MMLcset\subseteq}
+\defineXMLcommand [notsubset] {\MMLcset{\not\subset}}
+\defineXMLcommand [notprsubset] {\MMLcset{\not\subseteq}}
+\defineXMLcommand [setdiff] {\MMLcset\setminus}
+
+\def\MMLcset#1{\getXMLstackdata\plustwo#1\getXMLstackdata\plusthree}
+
+\defineXMLcommand [card] {\left\vert\flushXMLstackfrom\plustwo\right\vert}
+\defineXMLcommand [cartesianproduct] {\flushXMLstackwith\plustwo\times}
+
+% sequences and series
+
+\defineXMLcommand [sum] {\MMLcSUMandPRODUCT{sum}\sum}
+\defineXMLcommand [product]{\MMLcSUMandPRODUCT{product}\prod}
+
+\setupMMLappearance[sum] [\c!location=\v!top]
+\setupMMLappearance[product][\c!location=\v!top]
+
+\def\stackMMLsubscripts#1%
+ {\vbox
+ {\baselineskip\zeropoint % hack, taco vragen
+ \halign{$\scriptstyle\hss##\hss$\cr#1\crcr}}}
+
+\def\MMLcSUMandPRODUCT#1#2%
+ {\begingroup
+ \XMLdoifonstackelse{condition,bvar,lowlimit}
+ {\def\MMLcSUMlow
+ {_{\XMLdoifonstackelse{condition}
+ {\collectXMLnamedstack{condition}{\crcr}%
+ \stackMMLsubscripts{\the\XMLRtoks}}
+ {\XMLdoifonstackelse{bvar}
+ {\XMLfirstnamed{bvar}%
+ \XMLdoifonstackelse{lowlimit}{=}{}}%
+ {}%
+ \XMLfirstnamed{lowlimit}}}}}
+ {\let\MMLcSUMlow\empty}%
+ \XMLdoifonstackelse{uplimit}
+ {\def\MMLcSUMup{^{\XMLfirstnamed{uplimit}}}}
+ {\let\MMLcSUMup\empty}%
+ \XMLdoifonstackelse{interval} % open math converter gives this
+ {\begingroup
+ \directsetup{mmc:interval:fetch}%
+ \XMLfirstnamed{interval}%
+ \endgroup
+ \ifx\MMCintervalfrom\empty\else
+ \def\MMLcSUMlow{_{\XMLdoifonstackelse{bvar}{\XMLfirstnamed{bvar}{=}}{}\MMCintervalfrom}}%
+ \fi
+ \ifx\MMCintervalto\empty \else
+ \def\MMLcSUMup{^{\MMCintervalto}}%
+ \fi}
+ {}%
+ \MMLcreset#2\doMMLlimits{#1}\MMLcSUMup\MMLcSUMlow
+ \directsetup{mmc:lambda:simple}% a bit of open math conversion mess
+ \MMLcreset\XMLfirstnamed{apply,lambda,ci}%
+ \endgroup}
+
+\defineXMLcommand [limit] {\directsetup{mmc:limit}}
+
+\setupMMLappearance[limit][\c!location=\v!top]
+
+\startsetups mmc:limit
+ \MMLcreset \lim
+ \doMMLlimits{limit}_{
+ \MMLcreset
+ \XMLdoifonstackelse {condition} {
+ \XMLfirstnamed{condition}
+ } {
+ \XMLdoifonstackelse {bvar} {
+ \XMLfirstnamed{bvar}\rightarrow
+ } {
+ }
+ \XMLfirstnamed{lowlimit}
+ }
+ }
+ \begingroup
+ \MMLcreset
+ \directsetup{mmc:lambda:simple}% a bit of open math conversion mess
+ \XMLfirstnamed{apply,lambda}% lambda needed for openmath
+ \endgroup
+\stopsetups
+
+\defineXMLcommand [tendsto] [type=default] {\directsetup{mmc:tendsto}}
+
+\startsetups mmc:tendsto
+ \MMLcreset \getXMLstackdata\plustwo
+ \processaction
+ [\XMLpar{tendsto}{type}{default}]
+ [ above=>\downarrow,
+ below=>\uparrow,
+ unknown=>\rightarrow]
+ \MMLcreset \getXMLstackdata\plusthree
+\stopsetups
+
+% elementary classical functions
+
+\defineXMLcommand [exp] {\directsetup{mmc:exp}}
+\defineXMLcommand [ln] {\directsetup{mmc:function}}
+\defineXMLcommand [log] {\directsetup{mmc:log}}
+\defineXMLignore [logbase]
+
+\setupMMLappearance[log][\c!location=\v!right]
+
+\startsetups mmc:exp
+ \getXMLentity{exponentiale}^{\XMLfirstnamed{apply,reln,ci,cn}}
+\stopsetups
+
+\startsetups mmc:log
+ \XMLdoifonstackelse {logbase} {
+ \doifelse\@@MMLloglocation\v!left {
+ \mathop{{}^{{\defineXMLprocess[logbase]\XMLfirstnamed{logbase}}}
+ \getXMLentity{NegThinSpace}
+ \getXMLentity{log}}
+ } {
+ \getXMLentity{log}_{{\defineXMLprocess[logbase]\XMLfirstnamed{logbase}}}
+ }
+ } {
+ \getXMLentity{log}
+ }
+ \MMLcreset
+ % mmc:function:argument assumes that the apply is second in the row (*1*)
+ % \removeXMLdatafromstack{logbase}
+ \directsetup{mmc:function:argument}
+\stopsetups
+
+% statistics
+
+\defineXMLcommand [mean] {\overline{\getXMLstackdata\plustwo}}
+\defineXMLcommand [sdev] {\sigma(\MMLcreset\getXMLstackdata\plustwo)}
+\defineXMLcommand [variance] {\sigma(\MMLcreset\getXMLstackdata\plustwo)^2}
+\defineXMLcommand [median] {\getXMLentity{median}(\MMLcreset\getXMLstackdata\plustwo)}
+\defineXMLcommand [mode] {\getXMLentity{mode}(\MMLcreset\getXMLstackdata\plustwo)}
+
+% moments
+
+\defineXMLcommand [moment] {\directsetup{mmc:moment}}
+\defineXMLprocess [momentabout]
+
+\startsetups mmc:moment
+ \left\langle\XMLfirstnamed{apply,reln,ci,cn}^{\XMLfirstnamed{degree}}\right\rangle
+ \XMLdoifonstackelse{momentabout} {
+ _{\XMLfirstnamed{momentabout}}
+ } {
+ }
+\stopsetups
+
+% linear algebra
+
+\defineXMLcommand [vector] {\directsetup{mmc:vector}} % sequence
+
+\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
+
+\defineXMLnested
+ [vector]
+ {\directsetup{mmc:vector:start}}
+ {\directsetup{mmc:vector:stop}}
+
+\startsetups mmc:vector:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:vector:stop
+ \stopsavingXMLelements
+ \ifnum\XMLstacklevel>\plusone
+ \doifelse\@@MMLvectordirection\v!horizontal {
+ \left(\flushXMLstackwith\plusone{\MMLseparator\@@MMLvectorseparator}\right)
+ } {
+ \collectXMLstack\crcr
+ \MMLcreset\left(\matrix{\the\XMLRtoks}\right)
+ }
+ \else
+ \overrightarrow{\charhtstrut\getXMLstackdata\plusone}
+ \fi
+ \endgroup
+\stopsetups
+
+\defineXMLnestedenvironmentsave [matrix] {} {\directsetup{mmc:matrix}}
+\defineXMLnestedenvironmentsave [matrixrow] {} {\directsetup{mmc:matrixrow}}
+
+\unexpanded\def\@col@amp@{&}
+
+\settrue\MMCdelmatrix %( ) when true
+
+\startsetups mmc:matrix
+ \begingroup
+ \MMLcreset
+ \defineXMLnestedenvironmentsave [matrixrow] {} {\directsetup{mmc:matrixrow:do}}
+ \ifconditional\MMCdelmatrix
+ \left(\matrix{\XMLflush{matrix}}\right)
+ \else
+ \settrue\MMCdelmatrix
+ \matrix{\XMLflush{matrix}}
+ \fi
+ \endgroup
+\stopsetups
+
+\startsetups mmc:matrixrow
+ \begingroup
+ \MMLcreset
+ \left(\matrix{\directsetup{mmc:matrixrow:do}}\right)
+ \endgroup
+\stopsetups
+
+\startsetups mmc:matrixrow:do
+ \begingroup
+ \startsavingXMLelements
+ \XMLflush{matrixrow}
+ \stopsavingXMLelements
+ \collectXMLstackrows\plusone\@col@amp@
+ \edef\ascii{\the\XMLRtoks}
+ \edef\ascii{\ascii}
+ \expandafter\endgroup\ascii\crcr
+\stopsetups
+
+\defineXMLcommand [determinant] {\directsetup{mmc:determinant}}
+\defineXMLcommand [transpose] {\directsetup{mmc:transpose}}
+\defineXMLcommand [selector] {\directsetup{mmc:selector}}
+
+\startsetups mmc:determinant
+ \begingroup
+ \left|
+ \setfalse\MMCdelmatrix
+ \getXMLstackdata\plustwo
+ \right|
+ \endgroup
+\stopsetups
+
+\startsetups mmc:transpose
+% \getXMLstackdata\plustwo^{\MMLrm T}
+ \getXMLstackdata\plustwo^{\mfunction{T}}
+\stopsetups
+
+\startsetups mmc:selector
+ \MMLmathinner{\getXMLstackdata\plustwo}_{\MMLcreset\flushXMLstackwith\plusthree{\MMLseparator,}}
+\stopsetups
+
+\defineXMLcommand [vectorproduct] {\getXMLstackdata\plustwo\getXMLentity{vectorproduct}\getXMLstackdata\plusthree}
+\defineXMLcommand [scalarproduct] {\getXMLstackdata\plustwo\getXMLentity{scalarproduct}\getXMLstackdata\plusthree}
+\defineXMLcommand [outerproduct] {\getXMLstackdata\plustwo\getXMLentity {outerproduct}\getXMLstackdata\plusthree}
+
+% semantic mapping elements
+
+\defineXMLnested
+ [semantics]
+ {\directsetup{mmc:semantics:start}}
+ {\directsetup{mmc:semantics:stop}}
+
+\startsetups mmc:semantics:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:semantics:stop
+ \stopsavingXMLelements
+ \XMLdoifonstackelse {annotation} {
+ \flushXMLnamedstackwith\plusone{annotation}\empty
+ } {
+ \flushXMLnamedstackwith\plusone{apply}\empty
+ }
+ \endgroup
+\stopsetups
+
+\defineXMLenvironmentsave
+ [annotation]
+ [encoding=]
+ {}
+ {\directsetup{mmc:annotation}}
+
+\startsetups mmc:annotation
+ \expanded{\doifinset{\XMLpar{annotation}{encoding}{}}{TeX,tex,TEX,ConTeXt,context,CONTEXT}} {
+ \XMLtexdata{annotation}
+ }
+\stopsetups
+
+\defineXMLignore [annotation-xml]
+
+% misc
+
+\defineXMLcommand [integers] {\getXMLentity{integers}}
+\defineXMLcommand [reals] {\getXMLentity{reals}}
+\defineXMLcommand [rationals] {\getXMLentity{rationals}}
+\defineXMLcommand [naturalnumbers] {\getXMLentity{naturalnumbers}}
+\defineXMLcommand [complexes] {\getXMLentity{complexes}}
+\defineXMLcommand [primes] {\getXMLentity{primes}}
+\defineXMLcommand [exponentiale] {\getXMLentity{ExponentialE}}
+\defineXMLcommand [imaginaryi] {\getXMLentity{ImaginaryI}}
+\defineXMLcommand [notanumber] {\mathop{\mfunction{NaN}}}
+\defineXMLcommand [true] {\mathop{\mfunction{true}}}
+\defineXMLcommand [false] {\mathop{\mfunction{false}}}
+\defineXMLcommand [emptyset] {\mathop{\O}}
+\defineXMLcommand [pi] {\pi}
+\defineXMLcommand [eulergamma] {\gamma}
+\defineXMLcommand [infinity] {\infty}
+
+% gonio functions
+
+\defineXMLcommand[sin] {\directsetup{mmc:function}} \defineXMLcommand[arcsin] {\directsetup{mmc:function}}
+\defineXMLcommand[sinh]{\directsetup{mmc:function}} \defineXMLcommand[arcsinh]{\directsetup{mmc:function}}
+\defineXMLcommand[cos] {\directsetup{mmc:function}} \defineXMLcommand[arccos] {\directsetup{mmc:function}}
+\defineXMLcommand[cosh]{\directsetup{mmc:function}} \defineXMLcommand[arccosh]{\directsetup{mmc:function}}
+\defineXMLcommand[tan] {\directsetup{mmc:function}} \defineXMLcommand[arctan] {\directsetup{mmc:function}}
+\defineXMLcommand[tanh]{\directsetup{mmc:function}} \defineXMLcommand[arctanh]{\directsetup{mmc:function}}
+\defineXMLcommand[cot] {\directsetup{mmc:function}} \defineXMLcommand[arccot] {\directsetup{mmc:function}}
+\defineXMLcommand[coth]{\directsetup{mmc:function}} \defineXMLcommand[arccoth]{\directsetup{mmc:function}}
+\defineXMLcommand[csc] {\directsetup{mmc:function}} \defineXMLcommand[arccsc] {\directsetup{mmc:function}}
+\defineXMLcommand[csch]{\directsetup{mmc:function}} \defineXMLcommand[arccsch]{\directsetup{mmc:function}}
+\defineXMLcommand[sec] {\directsetup{mmc:function}} \defineXMLcommand[arcsec] {\directsetup{mmc:function}}
+\defineXMLcommand[sech]{\directsetup{mmc:function}} \defineXMLcommand[arcsech]{\directsetup{mmc:function}}
+
+\setupMMLappearance[function][\c!reduction=\v!yes]
+
+\startsetups mmc:function
+ \getXMLentity\currentXMLelement
+ \ifx\MMLpowerelement\empty\else
+ ^{\MMLcreset\MMLpowerelement\empty}
+ \getXMLentity{NegThinSpace}
+ \global\let\MMLpowerelement\empty
+ \fi
+ \doif {\getXMLstackname\plusone} {\currentXMLelement} {
+ % rather fuzzy test; looks like an apply case
+ \directsetup{mmc:function:argument}
+ }
+\stopsetups
+
+\startsetups mmc:function:argument
+ \doifelse\@@MMLfunctionreduction\v!yes {
+ % \doifelse {\getXMLstackname\plustwo} {apply} {
+ % \doifelseMMCfunctioninapply \plustwo \MMLcfunctionlist \donefalse \donetrue
+ %
+ % best is to grab the apply (independent of order), (*1*), so:
+ %
+ \XMLdoifonstackelse {apply} {
+ \doifelseMMCfunctioninapply \XMLstackposition {\MMLcfunctionlist,divide} \donefalse \donetrue
+ } {
+ \donefalse
+ }
+ } {
+ \donetrue
+ }
+ % beware, we still flush from 2 up
+ \ifdone
+ \left(\MMLcreset\flushXMLstackfrom\plustwo\right)
+ \else
+ \MMLcreset\flushXMLstackfrom\plustwo
+ \fi
+\stopsetups
+
+% presentation mml
+
+\def\resetMMLseparator
+ {\newcounter\MMLxxcounter
+ \let\lastMMLseparator\empty}
+
+\def\grabMMLseparator#1%
+ {\increment\MMLxxcounter
+ \newcounter\MMLyycounter
+ \expanded{\dograbMMLseparator#1\noexpand\relax}}
+
+\def\dograbMMLseparator
+ {\increment\MMLyycounter
+ \doifnextcharelse\relax
+ {\lastMMLseparator\gobbleoneargument}
+ {\doifnextcharelse\xmlrent\grabMMLseparatora\grabMMLseparatorb}}
+
+\def\grabMMLseparatora#1\xmlrent#2%
+ {\ifnum\MMLxxcounter=\MMLyycounter\space
+ \def\lastMMLseparator{\xmlrent{#2}}%
+ \fi
+ \dograbMMLseparator}
+
+\def\grabMMLseparatorb#1%
+ {\ifnum\MMLxxcounter=\MMLyycounter\space
+ \doifXMLentityelse{#1}
+ {\def\lastMMLseparator{\xmlrent{#1}}}
+ {\def\lastMMLseparator{#1}}%
+ \fi
+ \dograbMMLseparator}
+
+%
+
+\defineXMLargument [mi] \MMLpMI
+\defineXMLargument [mn] \MMLpMN
+\defineXMLargument [mo] \MMLpMO
+
+\def\MMLpMI#1%
+ {\begingroup
+ \setMMLpmathstyle{mstyle}%
+ #1%
+ \endgroup}
+
+% \def\MMLpMN#1%
+% {\begingroup
+% \MMLrm
+% \setMMLpmathstyle{mstyle}%
+% #1%
+% \endgroup}
+
+\def\MMLpMN#1%
+ {\mfunction{\setMMLpmathstyle{mstyle}#1}}
+
+\def\MMLpMO#1% yes or no
+ {\flattenXMLcontent{#1}%
+ \doifXMLentityelse\flattenedXMLcontent
+ {\getXMLentity\flattenedXMLcontent}
+ {\ConvertConstantAfter\doifinstringelse{\xmlrent}{#1} % TODO ! ! ! ! ! ! ! !
+ {#1}
+ {\hbox
+ {\setMMLpmathstyle{mstyle}%
+ \ignorespaces#1\unskip}}}}
+
+% we need to get rid of spaces: <mo> &RightArrow; </mo>
+
+\def\MMLpMO#1% yes or no
+ {\flattenXMLcontent{#1}%
+ \doifXMLentityelse\flattenedXMLcontent
+ {\getXMLentity\flattenedXMLcontent}
+ {\ignorespaces#1\removeunwantedspaces}}
+
+\def\doMMLleft #1{\pushmacro\left \let\left \empty\normalleft #1\popmacro\left}
+\def\doMMLright#1{\pushmacro\right\let\right\empty\normalright#1\popmacro\right}
+
+\let\MMLpopen \empty
+\let\MMLpclose\empty
+
+\defineXMLnested [mfenced] [open=(,close=),separators=]
+ {\directsetup{mmp:mfenced:start}}
+ {\directsetup{mmp:mfenced:stop}}
+
+\startsetups mmp:mfenced:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:mfenced:stop
+ \stopsavingXMLelements
+ \edef\MMLpopen {\XMLpar{mfenced}{open} {}}
+ \edef\MMLpclose{\XMLpar{mfenced}{close}{}}
+ \ifx\MMLpopen \space\let\MMLpopen \empty\fi
+ \ifx\MMLpclose\space\let\MMLpclose\empty\fi
+ \ifx\MMLpopen\empty
+ \ifx\MMLpclose\empty
+ \else
+ \doMMLleft.
+ \fi
+ \else
+ \doMMLleft\MMLpopen
+ \fi
+ \pushmacro\MMLpopen
+ \pushmacro\MMLpclose
+ \doifelsenothing{\XMLpar{mfenced}{separators}{}} {
+ \flushXMLstackfrom\plusone
+ } {
+ \resetMMLseparator
+ \flushXMLstackwith\plusone {
+ \begingroup
+ \let\myspecialnormalvert\myspecialstretchvert
+ \grabMMLseparator{\XMLpar{mfenced}{separators}{}}
+ \endgroup
+ }
+ }
+ \popmacro\MMLpclose
+ \popmacro\MMLpopen
+ \ifx\MMLpclose\empty
+ \ifx\MMLpopen\empty
+ \else
+ \doMMLright.
+ \fi
+ \else
+ \doMMLright\MMLpclose
+ \fi
+ \endgroup
+\stopsetups
+
+% \startbuffer
+% <math><mfenced separators="" open="(" close=")"><mi>x</mi></mfenced></math>
+% <math><mfenced separators="" open="" close=")"><mi>x</mi></mfenced></math>
+% <math><mfenced separators="" open="(" close="" ><mi>x</mi></mfenced></math>
+% <math><mfenced separators="" open="" close="" ><mi>x</mi></mfenced></math>
+% <math><mfenced separators="" open="" close=" "><mi>x</mi></mfenced></math>
+% \stopbuffer
+%
+% \processXMLbuffer
+
+\defineXMLnestedenvironmentsave [menclose] [notation=]
+ {\directsetup{mmp:menclose:start}}
+ {\directsetup{mmp:menclose:stop}}
+
+\startsetups mmp:menclose:start
+ \begingroup
+\stopsetups
+
+\startsetups mmp:menclose:stop
+ \doifelse{\XMLpar{menclose}{notation}{}}{longdiv} {
+ \overline{)\XMLflush{menclose}}
+ } {
+ \XMLflush{menclose}
+ }
+ \endgroup
+\stopsetups
+
+\defineXMLnested [mfrac] [linethickness=]
+ {\directsetup{mmp:mfrac:start}}
+ {\directsetup{mmp:mfrac:stop}}
+
+\startsetups mmp:mfrac:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:mfrac:stop
+ \stopsavingXMLelements
+ \doifXMLparelse{mfrac}{linethickness} {
+ \edef\theXMLpar{\XMLpar{mfrac}{linethickness}{1}}
+ \processaction
+ [\theXMLpar]
+ [ thin=>\scratchdimen=.2pt,
+ medium=>\scratchdimen=.4pt,
+ thick=>\scratchdimen=.8pt,
+ unknown=>\setdimensionwithunit\scratchdimen{\theXMLpar}{}]
+ {{\getXMLstackdata\plusone}\above\scratchdimen{\getXMLstackdata\plustwo}}
+ } {
+ \frac{\getXMLstackdata\plusone}{\getXMLstackdata\plustwo}
+ }
+ \endgroup
+\stopsetups
+
+\defineXMLargument
+ [ms]
+ [lquote=\xmlrent{quot},
+ rquote=\xmlrent{quot},
+ fontweight=,
+ fontstyle=,
+ mathstyle=,
+ mathvariant=,
+ background=,
+ color=]
+ {\MMLpSTRING}
+
+\def\MMLpSTRING#1%
+ {\hbox
+ {\tf % else encoding problems
+ \MMLpTEXT{\XMLpar{ms}{lquote}{}%
+ \doMMPpbackground{ms}{\doMMPpcolor{ms}{\setMMLptextstyle{ms}\ignorespaces#1\removeunwantedspaces}}%
+ \XMLpar{ms}{rquote}{}}}}
+
+\defineXMLenvironment
+ [mstyle]
+ [fontweight=,
+ fontstyle=,
+ mathstyle=,
+ mathvariant=,
+ background=,
+ color=]
+ {\begingroup}
+ {\endgroup}
+
+\defineXMLargument [mtext] [CPA] \MMLpTEXT
+\defineXMLargument [merror] [CPA] \MMLpERROR
+\defineXMLargument [mphantom] [CPA] \MMLpPHANTOM
+\defineXMLargument [mpadded] [CPA] \MMLpPADDED
+
+\mapXMLvalue{mmp}{normal} {\tf} \mapXMLvalue{mmp}{double-stuck} {\bf}
+\mapXMLvalue{mmp}{bolditalic} {\bi} \mapXMLvalue{mmp}{bold-italic} {\bi}
+\mapXMLvalue{mmp}{boldslanted}{\bs} \mapXMLvalue{mmp}{bold-slanted} {\bs}
+\mapXMLvalue{mmp}{boldnormal} {\bf} \mapXMLvalue{mmp}{bold} {\bf}
+\mapXMLvalue{mmp}{slanted} {\sl} \mapXMLvalue{mmp}{normalslanted}{\sl}
+\mapXMLvalue{mmp}{italic} {\it} \mapXMLvalue{mmp}{normalitalic} {\it}
+\mapXMLvalue{mmp}{fraktur} {\bf} \mapXMLvalue{mmp}{bold-fraktur} {\bf}
+\mapXMLvalue{mmp}{script} {\tf} \mapXMLvalue{mmp}{bold-script} {\bf}
+
+% and all kind of other crappy names
+
+\def\setMMLptextstyle#1%
+ {\XMLval{mmp}{\XMLpar{#1}{fontweight}{}\XMLpar{#1}{fontstyle}{}}{}}
+
+\def\setMMLpmathstyle#1%
+ {\XMLval{mmp}{\XMLpar{#1}{mathvariant}{}}{}}
+
+\def\doMMPpcolor#1#2%
+ {\doifXMLparelse{#1}{color}{\color[\XMLpar{#1}{color}{}]{#2}}{#2}}
+
+\def\doMMPpbackground#1#2%
+ {\doifXMLparelse{#1}{background}
+ {\inframed
+ [\c!frame=\v!off,
+ \c!background=\v!color,
+ \c!backgroundcolor=\XMLpar{#1}{background}{}]
+ {#2}}
+ {#2}}
+
+\def\MMLpTEXT#1%
+ {\hbox
+ {\tf % else encoding problems
+ \doMMPpbackground{ms}{\doMMPpcolor{ms}{\setMMLptextstyle{ms}\ignorespaces#1\removeunwantedspaces}}}}
+
+\def\MMLpERROR#1%
+ {\hbox{$\displaystyle#1$}}
+
+\def\MMLpPHANTOM#1%
+ {\phantom{\ignorespaces{}#1\unskip}} % watch spacing {} hack
+
+\def\MMLpPADDED#1%
+ {#1}
+
+% mrow
+
+\defineXMLenvironment [mrow] {\resetMMLbounds} {\finishMMLbounds}
+
+% \def\MMLleft #1{\increment\MMLboundslevel\left #1}
+% \def\MMLright#1{\right#1\decrement\MMLboundslevel}
+
+% \def\resetMMLbounds
+% {\let\MMLboundslevel\!!plusone\left.}
+
+% \def\finishMMLbounds
+% {\dorecurse\MMLboundslevel{\right.}}
+
+\def\resetMMLbounds
+ {\pushmacro\MMLboundslevel
+ \newcounter\MMLboundslevel}
+
+\def\MMLleft #1%
+ {\increment\MMLboundslevel
+ \normalleft#1}
+
+\def\MMLright#1%
+ {\ifnum\MMLboundslevel=0 \normalleft.\!\fi
+ \normalright#1%
+ \decrement\MMLboundslevel}
+
+\def\finishMMLbounds
+ {\ifnum\MMLboundslevel>0
+ \normalright.\!%
+ \decrement\MMLboundslevel
+ \expandafter\finishMMLbounds
+ \else
+ \popmacro\MMLboundslevel
+ \fi}
+
+\defineXMLnested [msqrt] {\directsetup{mmp:msqrt:start}} {\directsetup{mmp:msqrt:stop}}
+\defineXMLnested [mroot] {\directsetup{mmp:mroot:start}} {\directsetup{mmp:mroot:stop}}
+
+\startsetups mmp:msqrt:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:msqrt:stop
+ \stopsavingXMLelements
+ \sqrt{\flushXMLstackfrom\plusone}
+ \endgroup
+\stopsetups
+
+\startsetups mmp:mroot:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:mroot:stop
+ \stopsavingXMLelements
+ \root{\getXMLstackdata\plustwo}\of{\getXMLstackdata\plusone}
+ \endgroup
+\stopsetups
+
+\setupMMLappearance[scripts][\c!alternative=\v!a]
+
+\defineXMLnested [msub] {\directsetup{mmp:msub:start}} {\directsetup{mmp:msub:stop}}
+\defineXMLnested [msup] {\directsetup{mmp:msup:start}} {\directsetup{mmp:msup:stop}}
+\defineXMLnested [msubsup] {\directsetup{mmp:msbp:start}} {\directsetup{mmp:msbp:stop}}
+
+\startsetups mmp:msub:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:msub:stop
+ \stopsavingXMLelements
+ \doifelse\@@MMLscriptsalternative\v!a {
+ {\getXMLstackdata\plusone}_{\getXMLstackdata\plustwo}
+ } {
+ \getXMLstackdata\plusone_{\getXMLstackdata\plustwo}
+ }
+ \endgroup
+\stopsetups
+
+\startsetups mmp:msup:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:msup:stop
+ \stopsavingXMLelements
+ \doifelse\@@MMLscriptsalternative\v!a {
+ {\getXMLstackdata\plusone}^{\getXMLstackdata\plustwo}
+ } {
+ \getXMLstackdata\plusone^{\getXMLstackdata\plustwo}
+ }
+ \endgroup
+\stopsetups
+
+\startsetups mmp:msbp:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:msbp:stop
+ \stopsavingXMLelements
+ \getXMLstackdata\plusone_{\getXMLstackdata\plustwo}^{\getXMLstackdata\plusthree}
+ \endgroup
+\stopsetups
+
+\defineXMLnested [mover] {\directsetup{mmp:mover:start}} {\directsetup{mmp:mover:stop}}
+\defineXMLnested [munder] {\directsetup{mmp:munder:start}} {\directsetup{mmp:munder:stop}}
+\defineXMLnested [munderover] {\directsetup{mmp:munderover:start}} {\directsetup{mmp:munderover:stop}}
+
+\startsetups mmp:mover:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:mover:stop
+ \stopsavingXMLelements
+ \mathop{\vbox{\mathsurround\zeropoint\ialign{\hss##\hss\crcr\noalign{\kern3\points}%
+ \disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo}
+ \crcr\noalign{\kern3\points\nointerlineskip}%
+ \disabledelimiter\doMMLfiller{\getXMLstackdata\plusone}
+ \crcr}}}
+ \limits
+ \endgroup
+\stopsetups
+
+\startsetups mmp:munder:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:munder:stop
+ \stopsavingXMLelements
+ \mathop{\vtop{\mathsurround\zeropoint\ialign{\hss##\hss\crcr
+ \disabledelimiter\doMMLfiller{\getXMLstackdata\plusone}
+ \crcr\noalign{\kern3\points\nointerlineskip}%
+ \disabledelimiter\doMMLfiller{\getXMLstackdata\plustwo}
+ \crcr\noalign{\kern3\points}}}}
+ \limits
+ \endgroup
+\stopsetups
+
+\startsetups mmp:munderover:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:munderover:stop
+ \stopsavingXMLelements
+ \getXMLstackdata\plusone
+ _{\disablefiller\disabledelimiter\getXMLstackdata\plustwo}
+ ^{\disablefiller\disabledelimiter\getXMLstackdata\plusthree}
+ \endgroup
+\stopsetups
+
+\def\doMMLfiller#1% bugged
+ {\pushmacro\doMMLfiller
+ \let\doMMLfiller\gobbleoneargument
+ \gdef\dodoMMLfiller{\disablefiller\mathematics{#1}}%
+ \hbox
+ {\def\normalorfiller##1##2%
+ {\gdef\dodoMMLfiller{\enablefiller#1}%
+ \let\normalorfiller\gobbletwoarguments}%
+ $#1$}%
+ \popmacro\doMMLfiller
+ \dodoMMLfiller}
+
+% tables
+
+% obsolete: \setupMMLappearance[mtable][\c!alternative=\v!a]
+
+\mapXMLvalue {mmp:mtable} {align:left} {right}
+\mapXMLvalue {mmp:mtable} {align:right} {left}
+\mapXMLvalue {mmp:mtable} {align:center} {middle}
+
+\mapXMLvalue {mmp:mtable} {frame:none} {off}
+\mapXMLvalue {mmp:mtable} {frame:solid} {on}
+\mapXMLvalue {mmp:mtable} {frame:on} {on}
+
+\defineXMLnested
+ [mtable]
+ [columnalign=,
+ columnspacing=.25ex,
+ rowspacing=.25ex,
+ frame=,
+ color=,
+ background=]
+ {\directsetup{mmp:mtable:start}}
+ {\directsetup{mmp:mtable:stop}}
+
+\defineXMLnestedargument
+ [mtr]
+ {\MMPmtableHANDLEtr}
+
+\defineXMLnestedargument
+ [mlabeledtr]
+ {\MMPmtableHANDLEtr}
+
+\defineXMLnestedargument
+ [mtd]
+ [columnalign=,
+ columnspacing=.25ex,
+ rowspacing=.25ex,
+ frame=,
+ color=,
+ background=]
+ {\MMPmtableHANDLEtd}
+
+\startsetups mmp:mtable:start
+ \vcenter \bgroup
+ \MMLpTABLEsplitter{background} \c!backgroundcolor
+ \MMLpTABLEsplitter{color} \c!color
+ \MMLpTABLEmapper {frame} \c!frame
+ \MMLpTABLEmapper {columnalign}\c!align
+ \setMMLpunit{\XMLpar{mtable}{rowspacing}\empty}{.25ex}
+ \let\MMLpTABLEoffset\MMLpunit
+ \bTABLE[\c!frame=\v!off,\c!background=\v!color,\c!offset=\MMLpTABLEoffset]
+\stopsetups
+
+\startsetups mmp:mtable:stop
+ \eTABLE
+ \egroup
+\stopsetups
+
+\long\def\MMPmtableHANDLEtr#1{%
+ \bTR\ignorespaces#1\removeunwantedspaces\eTR
+}
+
+\long\def\MMPmtableHANDLEtd#1{%
+ \let\theMMLpTABLEmap\empty
+ \MMLpTABLEmap{background} \c!backgroundcolor
+ \MMLpTABLEmap{color} \c!color
+ \MMLpTABLEmap{frame} \c!frame
+ \MMLpTABLEmap{columnalign}\c!align
+ \expanded{\bTD[\theMMLpTABLEmap]}%
+ $\ignorespaces#1\removeunwantedspaces$\eTD
+}
+
+\def\MMLpTABLEmapper#1#2%
+ {\doifXMLparelse{mtable}{#1}
+ {\newcounter\MMLcounter
+ \def\docommand##1%
+ {\increment\MMLcounter
+ \expanded{\setupTABLE[column][\MMLcounter][#2=\XMLval{mmp:mtable}{#2:##1}\empty]}}%
+ \expanded{\processseparatedlist[\XMLpar{mtable}{#1}\empty]}[ ]\docommand}
+ {}}
+
+\def\MMLpTABLEsplitter#1#2%
+ {\doifXMLparelse{mtable}{#1}
+ {\newcounter\MMLcounter
+ \def\docommand##1%
+ {\increment\MMLcounter
+ \expanded{\setupTABLE[column][\MMLcounter][#2=##1]}}%
+ \expanded{\processseparatedlist[\XMLpar{mtable}{#1}\empty]}[ ]\docommand}
+ {}}
+
+\def\MMLpTABLEmap#1#2%
+ {\doifXMLparelse{mtd}{#1}
+ {\edef\theMMLpTABLEmap{#2=\XMLval{mmp:mtable}{#2:\XMLpar{mtd}{#1}\empty}\empty,\theMMLpTABLEmap}}
+ {}}
+
+\defineXMLsingular [mspace] [width=.5em] {\directsetup{mmp:mspace}}
+
+\startsetups mmp:mspace
+ \setMMLpunit{\XMLpar{mspace}{width}{}}{.5em}
+ \hskip\MMLpunit\relax
+\stopsetups
+
+\def\setMMLpunit#1#2% i've forgotten what this means
+ {\setbox\scratchbox=\hbox
+ {\edef\ascii{#1}%
+ \@EA\aftersplitstring\ascii\at.\to\ascii
+ \scratchcounter=\ifx\ascii\empty#1\else\ascii\fi
+ \unskip\unskip}%
+ \ifdim\wd\scratchbox=\zeropoint
+ \edef\MMLpunit{#1em}%
+ \else
+ \edefconvertedargument\ascii{#1}%
+ \convertasciiafter\doifinstringelse{em}{\ascii}{\edef\MMLpunit{#1}}{%
+ \convertasciiafter\doifinstringelse{ex}{\ascii}{\edef\MMLpunit{#1}}{%
+ \convertasciiafter\doifinstringelse{pt}{\ascii}{\edef\MMLpunit{#1}}{%
+ \edef\MMLpunit{#2}}}}%
+ \fi}
+
+% end of tables
+
+\def\setMMLpunit#1#2%
+ {\setbox\scratchbox=\hbox
+ {\edef\ascii{#1}%
+ \@EA\aftersplitstring\ascii\at.\to\ascii
+ \scratchcounter=\ifx\ascii\empty#1\else\ascii\fi
+ \unskip\unskip}%
+ \ifdim\wd\scratchbox=\zeropoint
+ \edef\MMLpunit{#1em}%
+ \else
+ \edefconvertedargument\ascii{#1}%
+ \convertasciiafter\doifinstringelse{em}{\ascii}{\edef\MMLpunit{#1}}{%
+ \convertasciiafter\doifinstringelse{ex}{\ascii}{\edef\MMLpunit{#1}}{%
+ \convertasciiafter\doifinstringelse{pt}{\ascii}{\edef\MMLpunit{#1}}{%
+ \edef\MMLpunit{#2}}}}%
+ \fi}
+
+\defineXMLsingular [mspace] [width=.5em] {\directsetup{mmp:mspace}}
+
+\startsetups mmp:mspace
+ \setMMLpunit{\XMLpar{mspace}{width}{}}{.5em}
+ \hskip\MMLpunit
+\stopsetups
+
+\defineXMLsingular [mglyph] [fontfamily=,index=1,alt=] {\directsetup{mmp:mglyph}}
+
+\startsetups mmp:mglyph
+ \def\MMLpglyph{\XMLpar{mglyph}{fontfamily}{}}%
+ \doifelsenothing{\MMLpglyph} {
+ \hbox{\tttf[fontfamily unspecified]}
+ } {
+ \doifdefinedelse{\MMLpglyph} {
+ \hbox{\getvalue{\MMLpglyph}\char0\XMLpar{mglyph}{index}{1}}
+ } {
+ \doifelsenothing{\XMLpar{mglyph}{alt}{}} {
+ \hbox{\tttf[unknown fontfamily \XMLpar{mglyph}{fontfamily}{}]}
+ } {
+ \hbox{\tttf\XMLpar{mglyph}{alt}{}}
+ }
+ }
+ }
+\stopsetups
+
+\defineXMLsingular [malignmark] {}
+\defineXMLsingular [none] {}
+\defineXMLsingular [mprescripts] {}
+
+\defineXMLnested
+ [mmultiscripts]
+ {\setups{mmp:mmultiscripts:start}}
+ {\setups{mmp:mmultiscripts:stop}}
+
+\startsetups mmp:mmultiscripts:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmp:mmultiscripts:stop
+ \stopsavingXMLelements
+ \donefalse
+ \scratchcounter\zerocount
+ \dorecurse\XMLstacklevel {
+ % watch the extra {}'s
+ \ifdone
+ \ifodd\scratchcounter
+ _{\getXMLstackdata\recurselevel}
+ \else
+ ^{\getXMLstackdata\recurselevel}{}
+ \fi
+ \else
+ \doif{\getXMLstackname\recurselevel}{mprescripts}{\donetrue{}}
+ \fi
+ \ifdone \advance\scratchcounter\plusone \fi
+
+ }
+ \donetrue
+ \scratchcounter\zerocount
+ \dorecurse\XMLstacklevel {
+ \ifdone
+ % watch the extra {}'s
+ \ifcase\scratchcounter
+ \getXMLstackdata\recurselevel
+ \else\ifodd\scratchcounter
+ _{\getXMLstackdata\recurselevel}
+ \else
+ ^{\getXMLstackdata\recurselevel}{}
+ \fi\fi
+ \fi
+ \doif{\getXMLstackname\recurselevel}{mprescripts}{\donefalse}
+ \ifdone \advance\scratchcounter\plusone \fi
+ }
+ \endgroup
+\stopsetups
+
+% experimental patches
+
+\startmoduletestsection
+
+\let\MMLdoL\donothing
+\let\MMLdoR\donothing
+
+\startsetups mmc:apply:start
+ \begingroup
+ \startsavingXMLelements
+\stopsetups
+
+\startsetups mmc:apply:stop
+ \stopsavingXMLelements
+ \MMLmathinner {
+ \expanded{\doifinsetelse{\getXMLstackname\plusone}{\MMLcmainresetlist,\MMLctempresetlist}}
+ \MMLcreset
+ \donothing
+ \ifcase\MMLapplydepth \else
+ \doifXMLparelse{apply}{open} \donothing{\getXMLarguments{apply}{open="("}}% slow
+ \doifXMLparelse{apply}{close}\donothing{\getXMLarguments{apply}{close=")"}}% slow
+ \fi
+ \advance\MMLapplydepth\plusone
+ \begingroup
+ \doifXMLparelse{apply}{open} % now inside the group
+ {\edef\MMLdoL{\noexpand\left \XMLpar{apply}{open} {(}}
+ \edef\MMLdoR{\noexpand\right\XMLpar{apply}{close}{)}}}
+ {\let\MMLdoL\donothing
+ \let\MMLdoR\donothing}
+ \let\MMLctempresetlist\empty
+ \doifelse {\getXMLstackname\plusone} {apply} {
+ % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
+ \doifelseMMCfunctioninapply \plusone {plus,minus} {
+% [a]
+ % yet incomplete and rather untested
+ % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
+ } {
+% [b]
+ \MMLcreset
+ }
+ \MMLdoL
+ \getXMLstackdata\plusone
+ \ifconditional\somepostponedMMLactions
+ \postponedMMLactions
+ \else
+ \left(\MMLcreset\getXMLstackdata\plustwo\right)
+ \fi
+ \MMLdoR
+ } {
+ \doifelse {\getXMLstackname\plusone} {fn} {
+% [c]
+ % \MMLdoL/R are to be taken care of in the next setup
+ \directsetup{mmc:fn:apply}
+ } {
+ \doifelse {\getXMLstackname\plusone} {csymbol} {
+ % \MMLdoL/R are to be taken care of in the next setup
+% [d]
+ \directsetup{mmc:csymbol:apply}
+ } {
+ \doifelse {\getXMLstackname\plusone} {ci} {
+% [e]
+ % \MMLdoL/R are to be taken care of in the next setup
+ \directsetup{mmc:ci:apply}
+ } {
+% [f]
+ \MMLdoL
+ \getXMLstackdata\plusone
+ \MMLdoR
+ }
+ }
+ }
+ }
+ \endgroup
+ \advance\MMLapplydepth\minusone
+ \directsetup{apply:flush}
+ }
+ \endgroup
+\stopsetups
+
+\startsetups mmc:fn:apply
+ \begingroup
+ \startsavingXMLelements
+ \rawXMLstacktext\plusone % still on stack, no check, just fn content
+ \stopsavingXMLelements
+ \doifelse {\getXMLstackname\plusone} {ci} {
+ \flattenXMLcontent{\getXMLstackdata\plusone}
+ \doifsetupselse{mmc:fn:\flattenedXMLcontent} {
+ % \MMLdoL/MMLdoR to be handled in plugin
+ \global\defXMLstackdata\XMLfnoperator\plusone
+ \expanded{\endgroup\noexpand\directsetup{mmc:fn:\flattenedXMLcontent}}
+ } {
+ \endgroup
+ \MMLcreset
+ \MMLdoL
+ \getXMLstackdata\plusone
+ \ifnum\XMLstacklevel>\plusone
+ \getXMLentity{NegThinSpace}
+ \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)
+ \fi
+ \MMLdoR
+ }
+ } {
+ \endgroup
+ \MMLcreset
+ \MMLdoL
+ \getXMLstackdata\plusone
+ \MMLdoR
+ }
+\stopsetups
+
+\startsetups mmc:csymbol:apply
+ \begingroup
+ \defineXMLsave[csymbol][definitionURL=,encoding=]
+ \rawXMLstackdata\plusone % was text % still on stack, no check, just attr test
+ % \MMLdoL/MMLdoR to be handled in plugin
+ \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL
+ \doifsetupselse{mmc:csymbol:\mmcSymbolURL} {
+ \expanded{\endgroup\noexpand\directsetup{mmc:csymbol:\mmcSymbolURL}}
+ } {
+ \endgroup
+ %\XMLval{mmc:cs}{\XMLop{encoding}}{\firstofoneargument}% fails when no content
+ \XMLval{mmc:cs}{\XMLop{encoding}}{}
+ }
+\stopsetups
+
+\defineXMLsingular
+ [csymbol]
+ [encoding=text,
+ definitionURL=]
+ {\directsetup{mmc:csymbol:apply:singular}}
+
+\startsetups mmc:csymbol:apply:singular
+ \lowercasestring\XMLpar{csymbol}{definitionURL}{}\to\mmcSymbolURL
+ \directsetup{mmc:csymbol:\mmcSymbolURL}
+\stopsetups
+
+\startsetups mmc:ci:apply
+ \getXMLstackdata\plusone
+ \ifnum\XMLstacklevel>\plusone
+ \left(\MMLcreset\flushXMLstackwith\plustwo{\MMLseparator,}\right)
+ \fi
+\stopsetups
+
+\def\xflushXMLstackwith#1#2#3#4% num bgroup egroup whatever
+ {\dostepwiserecurse{#1}\XMLstacklevel\plusone
+ {#2\relax
+ \ifnum\recurselevel>#1\relax#4\fi
+ \getXMLstackdata\recurselevel
+ #3}}
+
+\def\xflushXMLstackfrom#1#2#3%
+ {\dostepwiserecurse{#1}\XMLstacklevel\plusone
+ {#2\getXMLstackdata\recurselevel#3}}
+
+% <apply><divide/>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% </apply>
+
+\startsetups mmc:minus
+ \doif \@@MMLsignreduction \v!yes {
+ \setMMLcreset{fn,\MMLcfunctionlist}
+ }
+ \ifcase\XMLstacklevel
+ \or
+ % self
+ \or
+ -\getXMLstackdata\plustwo
+ \else
+ \dostepwiserecurse\plustwo\XMLstacklevel\plusone {
+ \begingroup
+ \doifelse {\getXMLstackname\recurselevel} {apply} {
+ \ifnum\recurselevel=\plustwo
+ \begingroup
+ \dodoifelseMMCfunctioninapply \recurselevel {minus} {
+ \ifnum\XMLstacklevel>\plustwo
+ \endgroup
+ \else
+ \endgroup
+ \MMLcreset
+ \fi
+ } {
+ \endgroup
+ }
+ \else
+ \doifelseMMCfunctioninapply \recurselevel {\MMLcfunctionlist,\MMLcconstructlist} {
+ \MMLcreset
+ } {
+ }
+ \fi
+ } {
+ }
+ \getXMLstackdata\recurselevel
+ \ifnum\recurselevel<\XMLstacklevel\relax
+ -
+ \fi
+ \endgroup
+ }
+ \fi
+\stopsetups
+
+\stopmoduletestsection
+
+\stopmodule
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-newmmo.mkii b/tex/context/modules/mkii/x-newmmo.mkii
new file mode 100644
index 000000000..97fdeb06c
--- /dev/null
+++ b/tex/context/modules/mkii/x-newmmo.mkii
@@ -0,0 +1,210 @@
+%D \module
+%D [ file=x-newmmo,
+%D version=2006.05.17,
+%D title=\CONTEXT\ XML Macros,
+%D subtitle=MathML Renderer/Open Math Extensions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Strange things, why not mapped onto normal content MathML and/or
+%D onto processing instructions.
+
+\unprotect
+
+%D \startbuffer
+%D <math xmlns="http://www.w3.org/1998/Math/MathML">
+%D <vector>
+%D <apply>
+%D <csymbol definitionURL="http://www.openmath.org/cd/nums1#rational"/>
+%D <ci>a</ci>
+%D <cn type="integer">2</cn>
+%D </apply>
+%D <ci>a</ci>
+%D </vector>
+%D </math>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/nums1\letterhash rational
+ \MMLcreset
+ \getXMLstackdata\plustwo/\getXMLstackdata\plusthree
+\stopsetups
+
+%D \startbuffer
+%D <math xmlns="http://www.w3.org/1998/Math/MathML">
+%D <apply>
+%D <csymbol definitionURL="http://www.openmath.org/cd/math4all#diffquot"/>
+%D <ci>y</ci>
+%D <ci>x</ci>
+%D </apply>
+%D </math>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash diffquot
+ \MMLcreset
+ \frac {
+ \Delta\getXMLstackdata\plustwo
+ } {
+ \Delta\getXMLstackdata\plusthree
+ }
+\stopsetups
+
+%D \startbuffer
+%D <math xmlns="http://www.w3.org/1998/Math/MathML">
+%D <apply>
+%D <csymbol definitionURL="http://www.openmath.org/cd/math4all#difference"/>
+%D <ci>y</ci>
+%D </apply>
+%D </math>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+%D
+%D \startbuffer
+%D <math xmlns="http://www.w3.org/1998/Math/MathML">
+%D <apply>
+%D <csymbol definitionURL="http://www.openmath.org/cd/math4all#difference"/>
+%D <apply>
+%D <eq/>
+%D <ci>y</ci>
+%D <apply>
+%D <minus/>
+%D <apply>
+%D <ci>f</ci>
+%D <ci>x</ci>
+%D </apply>
+%D <apply>
+%D <ci>f</ci>
+%D <apply>
+%D <minus/>
+%D <ci>x</ci>
+%D <cn type="integer">1</cn>
+%D </apply>
+%D </apply>
+%D </apply>
+%D </apply>
+%D </apply>
+%D </math>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash difference
+ \MMLcreset
+ \Delta\getXMLstackdata\plustwo
+\stopsetups
+
+%D \startbuffer
+%D <math xmlns="http://www.w3.org/1998/Math/MathML">
+%D <apply>
+%D <csymbol definitionURL="http://www.openmath.org/cd/math4all#diff"/>
+%D <ci>s</ci>
+%D <ci>t</ci>
+%D </apply>
+%D </math>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash diff
+ \MMLcreset
+ \frac {
+ \mfunction{\getXMLentity{mathematicald}}\getXMLstackdata\plustwo
+ } {
+ \mfunction{\getXMLentity{mathematicald}}\getXMLstackdata\plusthree
+ }
+\stopsetups
+
+%D A unit mess.
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@second {\mr s}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@minute {\mr m}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@hour {\mr h}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@day {\mr d}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@week {\mr w}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@month {\mr m}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@year {\mr y}\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@meter {\mr m}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@gram {\mr g}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@liter {\mr l}\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@watt {\mr W}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@pascal {\mr P}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@kelvin {\mr K}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@celsius {\mr C}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@newton {\mr N}\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@byte {\mr B}\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@pico {\mr p}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@micro \mu\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@milli {\mr m}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@centi {\mr c}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@deci {\mr d}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@deca {\mr d}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@hecto {\mr h}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@kilo {\mr k}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@mega {\mr m}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@giga {\mr g}\getXMLstackdata\plustwo\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_siprefix1@tera {\mr t}\getXMLstackdata\plustwo\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash procent \procent\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash promille \promille\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash degree ^\circ\stopsetups
+
+% whatever
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash triangle
+ \Delta\,
+\stopsetups
+
+% crap
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@degree_celsius
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@celsius}
+\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@degree_kelvin
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@kelvin}
+\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@metre
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@meter}
+\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@gramme
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@gram}
+\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@litre
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_metric1@liter}
+\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@calendar_month
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@month}
+\stopsetups
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@calendar_year
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash units_time1@year}
+\stopsetups
+
+\startsetups mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash degree_angle
+ \directsetup{mmc:csymbol:http://www.openmath.org/cd/mathadore\letterhash degree}
+\stopsetups
+
+\defineXMLargument
+ [ci]
+ {\checkMMLciSYMBOL}
+
+\def\checkMMLciSYMBOL#1%
+ {\defconvertedargument\ascii{#1}%
+ \executeifdefined{ci:symbol:crap:\ascii}{#1}}
+
+\setvalue{ci:symbol:crap:alpha}{\alpha}
+\setvalue{ci:symbol:crap:beta}{\beta}
+\setvalue{ci:symbol:crap:gamma}{\gamma}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-newpml.mkii b/tex/context/modules/mkii/x-newpml.mkii
new file mode 100644
index 000000000..ea3bae182
--- /dev/null
+++ b/tex/context/modules/mkii/x-newpml.mkii
@@ -0,0 +1,250 @@
+%D \module
+%D [ file=xtag-pml,
+%D version=2001.06.10,
+%D title=\CONTEXT\ XML Support,
+%D subtitle=Units,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt XML Macros / Units}
+
+\usemodule[newmml]
+
+%D Quick and dirty in||line units:
+%D
+%D \startbuffer
+%D <phys>
+%D <cn> 10 </cn>
+%D <cu> <Newton/> <Square/> <Meter/> <Per/> <Sec/> </cu>
+%D </phys>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+%D
+%D A more \MATHML||like unit application:
+%D
+%D \startbuffer
+%D <phys> <apply> <unit/>
+%D <cn> 10 </cn>
+%D <csymbol> <Square/> <Meter/> <Per/> <Sec/> </csymbol>
+%D </apply> </phys>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+%D
+%D A bit more compact:
+%D
+%D \startbuffer
+%D <phys> <apply> <unit/>
+%D <cn> 10 </cn>
+%D <cu> <Square/> <Meter/> <Per/> <Sec/> </cu>
+%D </apply> </phys>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+%D
+%D A bit more complicated:
+%D
+%D \startbuffer
+%D <phys> <apply> <unit/>
+%D <apply> <divide/> <ci> a </ci> <cn> 10 </cn> </apply>
+%D <cu> <Square/> <Meter/> <Per/> <Sec/> </cu>
+%D </apply> </phys>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+%D
+%D An alternative (equivalent) for \type {</cu>}:
+%D
+%D \startbuffer
+%D <phys> <apply> <unit/>
+%D <cn> 10 </cn> <cunseq> <Square/> <Meter/> <Per/> <Sec/> </cunseq>
+%D </apply> </phys>
+%D \stopbuffer
+%D
+%D \typebuffer \processXMLbuffer
+
+\usemodule[units]
+
+\unprotect
+
+\defineXMLargument [phys] \automathematics
+\defineXMLargument [iphys] \inlinemathematics
+\defineXMLargument [dphys] \displaymathematics
+
+\defineXMLcommand [unit] {\directsetup{pml:unit}}
+
+\startsetups pml:unit
+ \flushXMLstackwith\plustwo\relax
+\stopsetups
+
+% \defineXMLenvironment
+% [unit]
+% {\ignorespaces}
+% {\removeunwantedspaces}
+
+\defineXMLsingular
+ [unit]
+ [label=]
+ {\XMLop{label}}
+
+\defineXMLsingular
+ [unitmeaning]
+ [label=]
+ {\expanded{\unitmeaning{\XMLop{label}}}}
+
+\let\handlePMLunit\firstofoneargument
+
+%D All unit commands are remapped in a similar way.
+
+\defineXMLsingular [Atto] {\handlePMLunit\Atto}
+\defineXMLsingular [Femto] {\handlePMLunit\Femto}
+\defineXMLsingular [Pico] {\handlePMLunit\Pico}
+\defineXMLsingular [Nano] {\handlePMLunit\Nano}
+\defineXMLsingular [Micro] {\handlePMLunit\Micro}
+\defineXMLsingular [Milli] {\handlePMLunit\Milli}
+\defineXMLsingular [Centi] {\handlePMLunit\Centi}
+\defineXMLsingular [Deci] {\handlePMLunit\Deci}
+\defineXMLsingular [Hecto] {\handlePMLunit\Hecto}
+\defineXMLsingular [Kilo] {\handlePMLunit\Kilo}
+\defineXMLsingular [Mega] {\handlePMLunit\Mega}
+\defineXMLsingular [Giga] {\handlePMLunit\Giga}
+\defineXMLsingular [Terra] {\handlePMLunit\Terra}
+\defineXMLsingular [Peta] {\handlePMLunit\Peta}
+\defineXMLsingular [Exa] {\handlePMLunit\Exa}
+
+\defineXMLsingular [Times] {\handlePMLunit\Times}
+\defineXMLsingular [Solidus] {\handlePMLunit\Solidus}
+\defineXMLsingular [Per] {\handlePMLunit\Per}
+\defineXMLsingular [OutOf] {\handlePMLunit\OutOf}
+
+\defineXMLsingular [Linear] {\handlePMLunit\Linear}
+\defineXMLsingular [Square] {\handlePMLunit\Square}
+\defineXMLsingular [Cubic] {\handlePMLunit\Cubic}
+
+\defineXMLsingular [Inverse] {\handlePMLunit\Inverse}
+
+\defineXMLsingular [Degrees] {\handlePMLunit\Degrees}
+\defineXMLsingular [Meter] {\handlePMLunit\Meter}
+\defineXMLsingular [Liter] {\handlePMLunit\Liter}
+\defineXMLsingular [Sec] {\handlePMLunit\Sec}
+\defineXMLsingular [Year] {\handlePMLunit\Year}
+\defineXMLsingular [Month] {\handlePMLunit\Month}
+\defineXMLsingular [Week] {\handlePMLunit\Week}
+\defineXMLsingular [Day] {\handlePMLunit\Day}
+\defineXMLsingular [Hour] {\handlePMLunit\Hour}
+\defineXMLsingular [Min] {\handlePMLunit\Min}
+\defineXMLsingular [Minute] {\handlePMLunit\Min}
+\defineXMLsingular [Second] {\handlePMLunit\Sec}
+\defineXMLsingular [Rad] {\handlePMLunit\Rad}
+\defineXMLsingular [Deg] {\handlePMLunit\Deg}
+\defineXMLsingular [Hertz] {\handlePMLunit\Hertz}
+\defineXMLsingular [RevPerSec] {\handlePMLunit\RevPerSec}
+\defineXMLsingular [RevPerMin] {\handlePMLunit\RevPerMin}
+\defineXMLsingular [Gram] {\handlePMLunit\Gram}
+\defineXMLsingular [Atom] {\handlePMLunit\Atom}
+\defineXMLsingular [Newton] {\handlePMLunit\Newton}
+\defineXMLsingular [Pascal] {\handlePMLunit\Pascal}
+\defineXMLsingular [Joule] {\handlePMLunit\Joule}
+\defineXMLsingular [Watt] {\handlePMLunit\Watt}
+\defineXMLsingular [Celsius] {\handlePMLunit\Celsius}
+\defineXMLsingular [Kelvin] {\handlePMLunit\Kelvin}
+\defineXMLsingular [Fahrenheit] {\handlePMLunit\Fahrenheit}
+\defineXMLsingular [Mol] {\handlePMLunit\Mol}
+\defineXMLsingular [Molair] {\handlePMLunit\Molair}
+\defineXMLsingular [Equivalent] {\handlePMLunit\Equivalent}
+\defineXMLsingular [Farad] {\handlePMLunit\Farad}
+\defineXMLsingular [Ohm] {\handlePMLunit\Ohm}
+\defineXMLsingular [Siemens] {\handlePMLunit\Siemens}
+\defineXMLsingular [Ampere] {\handlePMLunit\Ampere}
+\defineXMLsingular [Coulomb] {\handlePMLunit\Coulomb}
+\defineXMLsingular [Volt] {\handlePMLunit\Volt}
+\defineXMLsingular [eVolt] {\handlePMLunit\eVolt}
+\defineXMLsingular [Tesla] {\handlePMLunit\Tesla}
+\defineXMLsingular [VoltAC] {\handlePMLunit\VoltAC}
+\defineXMLsingular [VoltDC] {\handlePMLunit\VoltDC}
+\defineXMLsingular [Baud] {\handlePMLunit\Baud}
+\defineXMLsingular [Bit] {\handlePMLunit\Bit}
+\defineXMLsingular [Byte] {\handlePMLunit\Byte}
+\defineXMLsingular [Bequerel] {\handlePMLunit\Bequerel}
+\defineXMLsingular [Sievert] {\handlePMLunit\Sievert}
+\defineXMLsingular [Candela] {\handlePMLunit\Candela}
+\defineXMLsingular [Bell] {\handlePMLunit\Bell}
+\defineXMLsingular [At] {\handlePMLunit\At}
+\defineXMLsingular [Atm] {\handlePMLunit\Atm}
+\defineXMLsingular [Bar] {\handlePMLunit\Bar}
+\defineXMLsingular [EVolt] {\handlePMLunit\EVolt}
+\defineXMLsingular [Foot] {\handlePMLunit\Foot}
+\defineXMLsingular [Inch] {\handlePMLunit\Inch}
+\defineXMLsingular [Cal] {\handlePMLunit\Cal}
+\defineXMLsingular [Force] {\handlePMLunit\Force}
+\defineXMLsingular [Lux] {\handlePMLunit\Lux}
+\defineXMLsingular [Gray] {\handlePMLunit\Gray}
+\defineXMLsingular [Weber] {\handlePMLunit\Weber}
+\defineXMLsingular [Henry] {\handlePMLunit\Henry}
+\defineXMLsingular [Sterant] {\handlePMLunit\Sterant}
+\defineXMLsingular [Angstrom] {\handlePMLunit\Angstrom}
+\defineXMLsingular [Gauss] {\handlePMLunit\Gauss}
+
+\defineXMLsingular [Percent] {\handlePMLunit\Percent}
+\defineXMLsingular [Promille] {\handlePMLunit\Promille}
+\defineXMLsingular [Permille] {\handlePMLunit\Permille}
+
+\defineXMLsingular [Unit] {\handlePMLunit\Unit}
+\defineXMLsingular [NoUnit] {\handlePMLunit\NoUnit}
+
+\protect \doifnotmode{demo}{\endinput}
+
+\starttext
+
+\startXMLdata
+<phys>
+ <apply> <times/>
+ <cn> 1 </cn>
+ <ci><unit><Milli/><Sec/><Per/><Square/><Kilo/><Meter/></unit> </ci>
+ </apply>
+</phys>
+\stopXMLdata
+
+\startXMLdata
+<phys>
+ <apply> <divide/>
+ <cn> 2 </cn>
+ <ci> <unit><Unit/><Milli/><Sec/><Per/><Square/><Kilo/><Meter/></unit> </ci>
+ </apply>
+</phys>
+\stopXMLdata
+
+\startXMLdata
+<phys>
+ <apply> <times/>
+ <cn> 3 </cn>
+ <ci> <unit> <Milli/> <Sec/> <Per/> <Square/> <Kilo/> <Meter/> </unit> </ci>
+ </apply>
+</phys>
+\stopXMLdata
+
+\startXMLdata
+<phys>
+ <apply> <times/>
+ <cn> 4 </cn>
+ <ci> <unit><Milli/><Sec/><Per/><Square/><Kilo/><Meter/></unit> </ci>
+ </apply>
+</phys>
+\stopXMLdata
+
+\startXMLdata
+<phys>
+ <apply> <times/>
+ <cn> 5 </cn>
+ <ci> <unit> <Milli/> <Sec/> <Per/> <Square/> <Kilo/> <Meter/> </unit> </ci>
+ </apply>
+</phys>
+\stopXMLdata
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-om2cml.xsl b/tex/context/modules/mkii/x-om2cml.xsl
new file mode 100644
index 000000000..4070d94dc
--- /dev/null
+++ b/tex/context/modules/mkii/x-om2cml.xsl
@@ -0,0 +1,1342 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ This style sheet is used in the Math4All project. This project
+ will provide an on-line math method for secondary and tertiary
+ education. In addition to the web-bases content the project
+ provides high quality typeset output as well.
+
+ This stylesheet is a copy of the one used by the group of Arjeh
+ Cohen (TU Eindhoven). This steet has multiple authors: David
+ Carlisle, and Clare M. So and Hans Cuypers (also see notice
+ below.)
+
+ In due time we may extend this sheet with options needed for the
+ project (alternative rendering, additional dictionaries).
+
+ Hans Hagen, PRAGMA ADE, Hasselt NL / 2006-04-14
+
+-->
+
+<!-- ********************************************************** -->
+<!-- XSL Transform of OpenMath to Content MathML -->
+<!-- (Based on initial version by David Carlisle) -->
+<!-- -->
+<!-- Author: Clare M. So <clare@scl.csd.uwo.ca> -->
+<!-- -->
+<!-- May to August 2002 -->
+<!-- -->
+<!-- (Last updated July 9, 2003) -->
+<!-- ********************************************************** -->
+
+<!-- ********************************************************** -->
+<!-- CHANGE LOG -->
+<!-- ********************************************************** -->
+<!-- May 13, 2003 - Add template nthdiff of calculus1 CD -->
+<!-- May 14, 2003 - Add templates for moreerrors CD -->
+<!-- May 15, 2003 - Split templates for multiset1, set1, -->
+<!-- and list1 CDs -->
+<!-- Split templates for s_dist1 and s_data1 CDs -->
+<!-- June 4, 2003 - Fix bugs in splitting set1, multiset1, and -->
+<!-- set1 CDs -->
+<!-- - Add templates for transc3 CD -->
+<!-- July 9, 2003 - Add template for nthdiff -->
+
+<!-- Special MathML entities -->
+
+<!DOCTYPE stylesheet [
+<!ENTITY pi "&#x003C0;">
+<!ENTITY e "&#x02147E;">
+<!ENTITY ee "&#x02147E;">
+<!ENTITY ExponentialE "&#x02147E;">
+<!ENTITY ImaginaryI "&#x02148;">
+<!ENTITY ii "&#x02148;">
+<!ENTITY gamma "&#x003B3;">
+<!ENTITY infin "&#x0221E;">
+<!ENTITY infty "&#x0221E;">
+<!ENTITY true "&#xF0002;">
+<!ENTITY false "&#xF0003;">
+<!ENTITY NotANumber "&#xF0001;">
+<!ENTITY NaN "&#xF0001;">
+]>
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:om="http://www.openmath.org/OpenMath"
+ xmlns="http://www.w3.org/1998/Math/MathML"
+ exclude-result-prefixes="om"
+ version="1.0">
+
+ <!-- xsl:output method="xml" indent="yes"/ -->
+ <xsl:output method="xml"/>
+
+ <xsl:strip-space elements="*"/>
+
+ <xsl:variable name="defaultOMSpriority">-10</xsl:variable>
+
+ <!-- **************************************************** -->
+ <!-- ****************** Basic Elements ****************** -->
+ <!-- **************************************************** -->
+
+ <!-- OMOBJ (D. Carlisle) / adapted by HH -->
+
+<xsl:template match="om:OMOBJ">
+ <xsl:choose>
+ <xsl:when test="@style='inline'">
+ <imath>
+ <xsl:apply-templates/>
+ </imath>
+ </xsl:when>
+ <xsl:when test="@style='display'">
+ <dmath>
+ <xsl:apply-templates/>
+ </dmath>
+ </xsl:when>
+ <xsl:otherwise>
+ <math>
+ <xsl:apply-templates/>
+ </math>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+ <!-- OMI (D. Carlisle) -->
+ <xsl:template match="om:OMI">
+ <cn type="integer">
+ <xsl:variable name="x" select="normalize-space(.)"/>
+ <xsl:choose>
+ <xsl:when test="contains($x,'x')">
+ <xsl:attribute name="base">16</xsl:attribute>
+ <xsl:value-of select="concat(substring-before($x,'x'),substring-after($x,'x'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$x"/> <!-- default is decimal -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </cn>
+ </xsl:template>
+
+ <!-- OMV (D. Carlisle) -->
+ <xsl:template match="om:OMV">
+ <ci>
+ <xsl:value-of select="normalize-space(@name)"/>
+ </ci>
+ </xsl:template>
+
+ <!-- OMF (decimal) -->
+ <xsl:template match="om:OMF[@dec]">
+ <cn>
+ <xsl:value-of select="normalize-space(@dec)"/>
+ </cn>
+ </xsl:template>
+
+ <!-- OMF (hex) -->
+ <xsl:template match="om:OMF[@hex]">
+ <cn base="16">
+ <xsl:value-of select="normalize-space(@hex)"/>
+ </cn>
+ </xsl:template>
+
+ <!-- OMA (D. Carlisle) -->
+ <xsl:template match="om:OMA">
+ <apply>
+ <xsl:apply-templates/>
+ </apply>
+ </xsl:template>
+
+ <!-- OMB -->
+ <!-- Note: No Content MathML equivalent -->
+ <xsl:template match="om:OMB">
+ <mtext definitionURL="http://www.openmath.org/objects#OMB">
+ <xsl:value-of select="."/>
+ </mtext>
+ </xsl:template>
+
+ <!-- OMSTR (D. Carlisle) -->
+ <!-- Note: mtext is a presentational MathML tag -->
+ <xsl:template match="om:OMSTR">
+ <mtext>
+ <xsl:value-of select="."/>
+ </mtext>
+ </xsl:template>
+
+ <!-- ***************************************************** -->
+ <!-- ****************** MathML group ******************** -->
+ <!-- ***************************************************** -->
+
+ <!-- Content Dicitionary: alg1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: zero, one -->
+
+ <!-- Trivial cases: none -->
+ <xsl:template match="om:OMS[@cd='alg1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- zero -->
+ <xsl:template match="om:OMS[@cd='alg1' and @name='zero']">
+ <cn type="integer">0</cn>
+ </xsl:template>
+
+ <!-- one -->
+ <xsl:template match="om:OMS[@cd='alg1' and @name='one']">
+ <cn type="integer">1</cn>
+ </xsl:template>
+
+ <!-- Content Dictionary: arith1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD conatains: abs, divide, gcd, lcm, minus, plus, power, product,
+ root, sum, unary_minus -->
+
+ <!-- Trivial Cases: abs, divide, gcd, lcm, minus, plus -->
+ <xsl:template match="om:OMS[@cd='arith1']">
+ <xsl:element name="{@name}">
+ <xsl:choose>
+ <xsl:when test="@name='times'">
+ <xsl:choose>
+ <xsl:when test="../@style='empty'">
+ <xsl:attribute name='symbol'></xsl:attribute>
+ </xsl:when>
+ <xsl:when test="../@style='cross'">
+ <xsl:attribute name='symbol'>times</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="../@style=''">
+ <!-- inherit from parent times -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name='symbol'><xsl:value-of select="../@style"/></xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="@name='divide'">
+ <xsl:choose>
+ <xsl:when test="../@style='inline'">
+ <xsl:attribute name='alternative'>b</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="@name='plus'">
+ <xsl:choose>
+ <xsl:when test="../@style='empty'">
+ <xsl:attribute name='alternative'>b</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- forget about it -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:template>
+
+ <!-- unary_minus -->
+ <xsl:template match="om:OMS[@cd='arith1' and @name='unary_minus']">
+ <minus/>
+ </xsl:template>
+
+ <!-- root -->
+ <xsl:template match="om:OMA[om:OMS[@cd='arith1' and @name='root']]">
+ <apply>
+ <root/>
+ <degree>
+ <xsl:apply-templates select="*[3]"/>
+ </degree>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- sum and product -->
+ <xsl:template match="om:OMA[om:OMS[@cd='arith1' and (@name='sum' or @name='product')]]">
+ <apply>
+ <xsl:element name="{om:OMS[1]/@name}"/>
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="3"/> <!-- the bounded var is in the func -->
+ </xsl:apply-templates>
+ </bvar>
+ <xsl:apply-templates select="*[2]"/> <!-- range of product/summation -->
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: bigfloat1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: bigfloat, bigfloatprec -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- bigfloat -->
+ <xsl:template match="om:OMA[om:OMS[@cd='bigfloat1' and @name='bigfloat']]">
+ <apply>
+ <times/>
+ <xsl:apply-templates select="*[2]"/>
+ <apply>
+ <power/>
+ <xsl:apply-templates select="*[3]"/>
+ <xsl:apply-templates select="*[4]"/>
+ </apply>
+ </apply>
+ </xsl:template>
+
+ <!-- bigfloatprec -->
+ <!-- Note: No Content MathML equivalent -->
+ <xsl:template match="om:OMS[@cd='bigfloat1' and @name='bigfloatprec']">
+ <csymbol encoding="OpenMath"
+ definitionURL="http://www.openmath.org/cd/bigfloat1#bigfloatprec"/>
+ </xsl:template>
+
+ <!-- Content Dictionary: calculus1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: defint, diff, int, nthdiff, partialdiff -->
+
+ <!-- Trivial cases: partialdiff -->
+ <xsl:template match="om:OMS[@cd='calculus1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- diff, int -->
+ <xsl:template match="om:OMA[om:OMS[@cd='calculus1' and (@name='diff' or @name='int')]]">
+ <apply>
+ <xsl:element name="{om:OMS[1]/@name}"/>
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="2"/>
+ </xsl:apply-templates>
+ </bvar>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- defint -->
+ <xsl:template match="om:OMA[om:OMS[@cd='calculus1' and @name='defint']]">
+ <apply>
+ <int/> <!-- pretty much the same as sum and product... CHECK domainofapp -->
+ <bvar> <!-- perphaps write a method for the similar parts... -->
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="3"/>
+ </xsl:apply-templates>
+ </bvar>
+ <xsl:apply-templates select="*[2]"/> <!-- range of diff -->
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- nthdiff -->
+ <xsl:template match="om:OMA[om:OMS[@cd='calculus1' and @name='nthdiff']]">
+ <apply>
+ <diff/>
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="3"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="*[2]"/>
+ </bvar>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionaries: complex1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: argument, complex_cartesian, complex_polar, conjugate,
+ imaginary, real -->
+
+ <!-- Trivial cases: conjugate, imaginary, real -->
+ <xsl:template match="om:OMS[@cd='complex1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- argument -->
+ <xsl:template match="om:OMS[@cd='complex1' and @name='argument']">
+ <arg/>
+ </xsl:template>
+
+ <!-- complex_cartesian or complex_polar -->
+ <xsl:template match="om:OMA[om:OMS[@cd='complex1' and (@name='complex_cartesian' or @name='complex_polar')]]">
+ <xsl:variable name="type_name" select="translate(om:OMS[1]/@name,'_','-')"/>
+ <xsl:choose>
+ <xsl:when test="child::om:OMV or child::om:OMA">
+ <apply>
+ <csymbol definitionURL="{concat('http://www.openmath.org/cd/complex1#',om:OMS[1]/@name)}"/>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:when>
+ <xsl:otherwise>
+ <cn type="{$type_name}">
+ <xsl:apply-templates select="*[2]" mode="convert"/>
+ <sep/>
+ <xsl:apply-templates select="*[3]" mode="convert"/>
+ </cn>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Content Dictionary: fns1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: domain, domainofapplication, identity, image, inverse,
+ lambda, left_compose, left_inverse, right_inverse -->
+
+ <!-- Trivial cases: domain, image, inverse -->
+ <xsl:template match="om:OMS[@cd='fns1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- domainofapplication -->
+ <xsl:template match="om:OMA[om:OMS[@cd='fns1' and @name='domainofapplication']]">
+ <domainofapplication>
+ <xsl:apply-templates select="*[2]"/>
+ </domainofapplication>
+ </xsl:template>
+
+ <!-- identity -->
+ <xsl:template match="om:OMS[@cd='fns1' and @name='identity']">
+ <ident/>
+ </xsl:template>
+
+ <!-- lambda -->
+ <xsl:template match="om:OMBIND[om:OMS[@cd='fns1' and @name='lambda']]">
+ <lambda>
+ <xsl:for-each select="om:OMBVAR/child::om:OMV">
+ <bvar>
+ <xsl:apply-templates select="."/>
+ </bvar>
+ </xsl:for-each>
+ <xsl:apply-templates select="*[3]"/>
+ </lambda>
+ </xsl:template>
+
+ <!-- range -->
+ <xsl:template match="om:OMS[@cd='fns1' and @name='range']">
+ <codomain/>
+ </xsl:template>
+
+ <!-- left_compose -->
+ <xsl:template match="om:OMS[@cd='fns1' and @name='left_compose']">
+ <compose/>
+ </xsl:template>
+
+ <!-- left_inverse -->
+ <xsl:template match="om:OMS[@cd='fns1' and @name='left_inverse']">
+ <inverse/>
+ </xsl:template>
+
+ <!-- right_inverse -->
+ <!-- Note: No Content MathML equivalent -->
+ <xsl:template match="om:OMS[@cd='fns1' and @name='right_inverse']">
+ <inverse encoding="OpenMath" definitionURL="http://www.openmath.org/cd/fns1#right_inverse"/>
+ </xsl:template>
+
+ <!-- Content Dictionary: integer1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: factorial, factorof, quotient, remainder -->
+
+ <!-- Trivial cases: factorof, factorial, quotient -->
+ <xsl:template match="om:OMS[@cd='integer1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- remainder -->
+ <xsl:template match="om:OMS[@cd='integer1' and @name='remainder']">
+ <rem/>
+ </xsl:template>
+
+ <!-- Content Dictionary: interval1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: integer_interval, interval, interval_oo, interval_cc,
+ interval_oc, interval_co -->
+
+ <!-- Trivial case: none -->
+
+ <!-- (All) -->
+ <xsl:template match="om:OMA[om:OMS[@cd='interval1']]">
+ <interval>
+ <xsl:choose>
+ <xsl:when test="om:OMS[1]/@name='interval_oo'">
+ <xsl:attribute name='closure'>open</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="om:OMS[1]/@name='interval_cc'">
+ <xsl:attribute name='closure'>closed</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="om:OMS[1]/@name='interval_oc'">
+ <xsl:attribute name='closure'>open-closed</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="om:OMS[1]/@name='interval_co'">
+ <xsl:attribute name='closure'>closed-open</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:apply-templates select="*[3]"/>
+ </interval>
+ </xsl:template>
+
+ <!-- Content Dictionary: linalg1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: determinant, matrix_selector, outerproduct,
+ scalarproduct, transpose, vector_selector, vector_product -->
+
+ <!-- Trivial cases: determinant, outerproduct, scalarproduct, transpose,
+ vectorproduct -->
+ <xsl:template match="om:OMS[@cd='linalg1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- vector_selector -->
+ <xsl:template match="om:OMA[om:OMS[@cd='linalg1' and @name='vector_selector']]">
+ <apply>
+ <selector/>
+ <xsl:apply-templates select="*[3]"/> <!-- the vector -->
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- matrix_selector -->
+ <xsl:template match="om:OMA[om:OMS[@cd='linalg1' and @name='matrix_selector']]">
+ <apply>
+ <selector/>
+ <xsl:apply-templates select="*[4]"/> <!-- the matrix -->
+ <xsl:apply-templates select="*[3]"/>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: linalg2 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: matrix, matrixrow, vector -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- matrixrow, matrix -->
+ <xsl:template match="om:OMA[om:OMS[@cd='linalg2']]">
+ <xsl:element name="{om:OMS[1]/@name}">
+ <xsl:apply-templates select="*[position()>1]"/>
+ </xsl:element>
+ </xsl:template>
+
+ <!-- (row) vector -->
+ <xsl:template match="om:OMA[om:OMS[@cd='linalg2' and @name='vector']]">
+ <apply>
+ <transpose/>
+ <vector>
+ <xsl:apply-templates select="*[position()>1]"/>
+ </vector>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: limit1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: above, below, bothsides, limit, null -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- both_sides, above, below, null -->
+ <xsl:template match="om:OMA[om:OMS[@cd='limit1']]">
+ <apply>
+ <limit/>
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="4"/>
+ </xsl:apply-templates>
+ </bvar>
+ <xsl:choose>
+ <xsl:when test="om:OMS[2]/@name='null'">
+ <lowlimit>
+ <xsl:apply-templates select="*[2]"/>
+ </lowlimit>
+ </xsl:when>
+ <xsl:otherwise>
+ <condition>
+ <apply>
+ <tendsto>
+ <xsl:choose>
+ <xsl:when test="om:OMS[2]/@name='both_sides'">
+ <xsl:attribute name="type">all</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="om:OMS[2]/@name='above'">
+ <xsl:attribute name="type">above</xsl:attribute>
+ </xsl:when>
+ <xsl:when test="om:OMS[2]/@name='below'">
+ <xsl:attribute name="type">below</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ </tendsto>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="4"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </condition>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="*[4]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: list1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: list, map, suchthat -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- list -->
+ <xsl:template match="om:OMA[om:OMS[@cd='list1' and @name='list']]">
+ <list>
+ <xsl:apply-templates select="*[position()>1]"/>
+ </list>
+ </xsl:template>
+
+ <!-- map -->
+ <xsl:template match="om:OMA[om:OMS[@cd='list1' and @name='map']]">
+ <list>
+ <xsl:apply-templates select="." mode="map"/>
+ </list>
+ </xsl:template>
+
+ <!-- suchthat -->
+ <xsl:template match="om:OMA[om:OMS[@cd='list1' and @name='suchthat']]">
+ <list>
+ <xsl:apply-templates select="." mode="suchthat"/>
+ </list>
+ </xsl:template>
+
+ <!-- Content Dictionary: logic1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: and, equivalent, false, implies, not, or, true, xor -->
+
+ <!-- Trivial cases: all -->
+ <xsl:template match="om:OMS[@cd='logic1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- Content Dictionary: mathmltypes -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: complex_cartesian_type, complex_polar_type, constant_type,
+ fn_type, integer_type, list_type, matrix_type, rational_type, real_type,
+ set_type, type, vector_type -->
+
+ <!-- (All mathmltypes elements) -->
+ <xsl:template match="om:OMATTR[om:OMATP[om:OMS[@cd='mathmltypes' and @name='type']]]">
+ <xsl:variable name="type_name" select="normalize-space(translate(substring-before(om:OMATP/om:OMS[2]/@name,'_type'),'_','-'))"/>
+ <xsl:choose>
+ <xsl:when test="*[2]=om:OMV">
+ <ci type="{$type_name}">
+ <xsl:value-of select="normalize-space(*[2]/@name)"/>
+ </ci>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMI">
+ <cn type="{$type_name}">
+ <xsl:variable name="x" select="normalize-space(*[2])"/>
+ <xsl:choose>
+ <xsl:when test="contains($x,'x')">
+ <xsl:attribute name="base">16</xsl:attribute>
+ <xsl:value-of select="concat(substring-before($x,'x'),substring-after($x,'x'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$x"/> <!-- default is decimal -->
+ </xsl:otherwise>
+ </xsl:choose>
+ </cn>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMF[@dec]">
+ <cn type="{$type_name}">
+ <xsl:value-of select="normalize-space(*[2]/@dec)"/>
+ </cn>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMF[@hex]">
+ <cn type="{$type_name}" base="16">
+ <xsl:value-of select="normalize-space(*[2]/@hex)"/>
+ </cn>
+ </xsl:when>
+ <xsl:otherwise> <!-- MathML cannot add type attribute to other objects -->
+ <xsl:comment>
+ Content MathML cannot add type <xsl:value-of select="$type_name"/> for the object after this comment.
+ </xsl:comment>
+ <xsl:apply-templates select="*[2]"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Content Dictionary: minmax1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: max, min -->
+ <xsl:template match="om:OMS[@cd='minmax1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- Trivial cases: none -->
+
+ <!-- max, min -->
+ <xsl:template match="om:OMA[om:OMS[@cd='minmax1']]">
+ <apply>
+ <xsl:element name="{om:OMS/@name}"/>
+ <xsl:choose>
+ <xsl:when test="*[2]=om:OMA[om:OMS[@cd='set1' and @name='set']]">
+ <xsl:apply-templates select="om:OMA/*[position()>1]"/>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMA[om:OMS[@cd='multiset1' and @name='multiset']]">
+ <xsl:apply-templates select="om:OMA/*[position()>1]"/>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMA[om:OMS[@cd='set1' and @name='suchthat']]">
+ <xsl:apply-templates select="*[2]" mode="suchthat"/>
+ </xsl:when>
+ <xsl:when test="*[2]=om:OMA[om:OMS[@cd='set1' and @name='map']]">
+ <xsl:apply-templates select="*[2]" mode="map"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <bvar><ci>x</ci></bvar>
+ <condition>
+ <apply>
+ <in/>
+ <ci>x</ci>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </condition>
+ </xsl:otherwise>
+ </xsl:choose>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: multiset1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: cartesian_product, emptyset, in, intersect, multiset,
+ notin, notprsubset, notsubset, prsubset, setdiff, size, subset, union -->
+
+ <!-- Trivial cases: emptyset, in, interset, notin, notprsubset, notsubset, prsubset,
+ subset, union -->
+ <xsl:template match="om:OMS[@cd='multiset1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- cartesian_product -->
+ <xsl:template match="om:OMS[@cd='multiset1' and @name='cartesian_product']">
+ <cartesianproduct/>
+ </xsl:template>
+
+
+ <!-- multiset -->
+ <xsl:template match="om:OMA[om:OMS[@cd='multiset1' and @name='multiset']]">
+ <set type="multiset">
+ <xsl:apply-templates select="*[position()>1]"/>
+ </set>
+ </xsl:template>
+
+ <!-- size -->
+ <xsl:template match="om:OMS[@cd='multiset1' and @name='size']">
+ <card/>
+ </xsl:template>
+
+ <!-- Content Dictionary: nums1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains based_integer, e, gamma, i, infinity, NaN, pi, rational -->
+
+ <!-- Trivial cases: pi, infinity -->
+ <xsl:template match="om:OMS[@cd='nums1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- based_integer -->
+ <!-- Note: Content MathML does not support base that is represented by a variable -->
+ <xsl:template match="om:OMA[om:OMS[@cd='nums1' and @name='based_integer']]">
+ <xsl:choose>
+ <xsl:when test="*[2]=om:OMV">
+ <apply>
+ <csymbol encoding="OpenMath" definitionURL="http://www.openmath.org/cd/nums1#based_integer"/>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:when>
+ <xsl:otherwise>
+ <cn type="integer" base="{normalize-space(*[2])}">
+ <xsl:value-of select="normalize-space(om:OMSTR)"/>
+ </cn>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- e -->
+ <xsl:template match="om:OMS[@cd='nums1' and @name='e']">
+ <exponentiale/>
+ </xsl:template>
+
+ <!-- gamma -->
+ <xsl:template match="om:OMS[@cd='nums1' and @name='gamma']">
+ <eulergamma/>
+ </xsl:template>
+
+ <!-- i -->
+ <xsl:template match="om:OMS[@cd='nums1' and @name='i']">
+ <imaginaryi/>
+ </xsl:template>
+
+ <!-- NaN -->
+ <xsl:template match="om:OMS[@cd='nums1' and @name='NaN']">
+ <notanumber/>
+ </xsl:template>
+
+ <!-- rational -->
+ <!-- Note: Content MathML does not support rational numbers that are
+ made up of variables or other mathematical objects -->
+ <xsl:template match="om:OMA[om:OMS[@cd='nums1' and @name='rational']]">
+ <xsl:choose>
+ <xsl:when test="child::om:OMV or child::om:OMA">
+ <apply>
+ <csymbol definitionURL="http://www.openmath.org/cd/nums1#rational"/>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:when>
+ <xsl:otherwise>
+ <cn type="rational">
+ <xsl:apply-templates select="*[2]" mode="convert"/>
+ <sep/>
+ <xsl:apply-templates select="*[3]" mode="convert"/>
+ </cn>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Content Dictionary: piece1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: otherwise, piece, piecewise -->
+
+ <!-- Trivial cases: (All of the OMSs here are almost trivial, except
+ that these functions are used without "apply" in Content MathML) -->
+
+ <!-- piecewise, piece, otherwise -->
+ <xsl:template match="om:OMA[om:OMS[@cd='piece1']]">
+ <xsl:element name="{om:OMS/@name}">
+ <xsl:apply-templates select="*[position()>1]"/>
+ </xsl:element>
+ </xsl:template>
+
+ <!-- Content Dictionary: quant1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: forall, exists -->
+
+ <!-- forall,exists -->
+ <xsl:template match="om:OMBIND[om:OMS[@cd='quant1']]">
+ <apply>
+ <xsl:element name="{om:OMS[1]/@name}"/>
+ <xsl:for-each select="om:OMBVAR/om:OMV">
+ <bvar>
+ <xsl:apply-templates select="."/>
+ </bvar>
+ </xsl:for-each>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: relation1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: approx, eq, geq, gt, leq, lt, neq -->
+
+ <!-- Trivial cases: all -->
+
+ <xsl:template match="om:OMS[@cd='relation1']">
+ <xsl:element name="{@name}">
+ <xsl:if test="../@style!=''">
+ <xsl:attribute name='align'><xsl:value-of select="../@style"/></xsl:attribute>
+ </xsl:if>
+ </xsl:element>
+ </xsl:template>
+
+ <!-- Content Dictionary: setname1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: C, N, P, Q, R, Z -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- P -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='P']">
+ <primes/>
+ </xsl:template>
+
+ <!-- N -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='N']">
+ <naturalnumbers/>
+ </xsl:template>
+
+ <!-- Z -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='Z']">
+ <integers/>
+ </xsl:template>
+
+ <!-- Z -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='Q']">
+ <rationals/>
+ </xsl:template>
+
+ <!-- R -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='R']">
+ <reals/>
+ </xsl:template>
+
+ <!-- C -->
+ <xsl:template match="om:OMS[@cd='setname1' and @name='C']">
+ <complexes/>
+ </xsl:template>
+
+ <!-- Content Dictionary: rounding1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: ceiling, floor, round, trunc -->
+
+ <!-- Trivial Cases: ceiling, floor -->
+ <xsl:template match="om:OMS[@cd='rounding1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- trunc -->
+ <xsl:template match="om:OMA[om:OMS[@cd='rounding1' and @name='trunc']]">
+ <apply>
+ <quotient/>
+ <xsl:apply-templates select="*[2]"/>
+ <cn>1</cn>
+ </apply>
+ </xsl:template>
+
+ <!-- round -->
+ <xsl:template match="om:OMA[om:OMS[@cd='rounding1' and @name='round']]">
+ <piecewise>
+ <piece>
+ <apply>
+ <floor/>
+ <apply>
+ <plus/>
+ <cn>0.5</cn>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </apply>
+ <apply>
+ <geq/>
+ <xsl:apply-templates select="*[2]"/>
+ <cn>0</cn>
+ </apply>
+ </piece>
+ <piece>
+ <apply>
+ <ceiling/>
+ <apply>
+ <minus/>
+ <xsl:apply-templates select="*[2]"/>
+ <cn>0.5</cn>
+ </apply>
+ </apply>
+ <apply>
+ <lt/>
+ <xsl:apply-templates select="*[2]"/>
+ <cn>0</cn>
+ </apply>
+ </piece>
+ </piecewise>
+ </xsl:template>
+
+ <!-- Content Dictionary: set1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: cartesian_product, emptyset, in, intersect, map, notin,
+ notprsubset, notsubset, prsubset, set, setdiff, size, subset, suchthat, union -->
+
+ <!-- Trivial cases: emptyset, in, intersect, notin, notprsubset, notsubset, prsubset
+ setdiff, subset, union -->
+ <xsl:template match="om:OMS[@cd='set1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- cartesian_product -->
+ <xsl:template match="om:OMS[@cd='set1' and @name='cartesian_product']">
+ <cartesianproduct/>
+ </xsl:template>
+
+ <!-- map -->
+ <xsl:template match="om:OMA[om:OMS[@cd='set1' and @name='map']]">
+ <set>
+ <xsl:apply-templates select="." mode="map"/>
+ </set>
+ </xsl:template>
+
+ <!-- size -->
+ <xsl:template match="om:OMS[@cd='set1' and @name='size']">
+ <card/>
+ </xsl:template>
+
+ <!-- suchthat -->
+ <xsl:template match="om:OMA[om:OMS[@cd='set1' and @name='suchthat']]">
+ <set>
+ <xsl:apply-templates select="." mode="suchthat"/>
+ </set>
+ </xsl:template>
+
+ <!-- Content Dictionary: s_data1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: mean, median, mode, moment, sdev, variance -->
+
+ <!-- Trivial cases: mean, median, mode, sdev, variance -->
+ <xsl:template match="om:OMS[@cd='s_data1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- moment -->
+ <xsl:template match="om:OMA[om:OMS[@cd='s_data1' and @name='moment']]">
+ <apply>
+ <moment/>
+ <degree>
+ <xsl:apply-templates select="*[2]"/>
+ </degree>
+ <momentabout>
+ <xsl:apply-templates select="*[3]"/>
+ </momentabout>
+ <xsl:apply-templates select="*[position()>3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: s_dist1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: mean, moment, sdev, variance -->
+
+ <!-- Trivial cases: mean, sdev, variance -->
+ <xsl:template match="om:OMS[@cd='s_dist1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- moment -->
+ <xsl:template match="om:OMA[om:OMS[@cd='s_dist1' and @name='moment']]">
+ <apply>
+ <moment/>
+ <degree>
+ <xsl:apply-templates select="*[2]"/>
+ </degree>
+ <momentabout>
+ <xsl:apply-templates select="*[3]"/>
+ </momentabout>
+ <xsl:apply-templates select="*[position()>3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: transc1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: arccos, arccosh, arccot, arccoth, arccsc,
+ arccsch, arcsec, arcsech, arcsin, arcsinh, arctan, arctanh, cos,
+ cosh, cot, coth, csc, csch, exp, ln, log, sec, sech, sin, sinh,
+ tan, tanh -->
+
+ <!-- Trivial cases: all except log -->
+ <xsl:template match="om:OMS[@cd='transc1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- log -->
+ <xsl:template match="om:OMA[om:OMS[@cd='transc1' and @name='log']]">
+ <apply>
+ <log/>
+ <logbase>
+ <xsl:apply-templates select="*[2]"/>
+ </logbase>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- Content Dictionary: veccalc1 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: curl, divergence, grad, Laplacian -->
+
+ <!-- Trivial cases: all except Laplacian -->
+ <xsl:template match="om:OMS[@cd='veccalc1']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- Laplacian -->
+ <!-- Note: Capital "L" -->
+ <xsl:template match="om:OMS[@cd='veccalc1' and @name='Laplacian']">
+ <laplacian/>
+ </xsl:template>
+
+ <!-- Content Dictionary: altenc -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: TeX_encoding, MathML_encoding -->
+
+ <!-- Trivial cases: none -->
+
+ <!-- (Everything in altenc) -->
+ <xsl:template match="om:OMATTR[om:OMATP[om:OMS[@cd='altenc']]]">
+ <semantics>
+ <xsl:apply-templates select="*[2]"/>
+ <xsl:apply-templates select="om:OMATP/child::om:OMS"/>
+ </semantics>
+ </xsl:template>
+
+ <!-- MathML_encoding -->
+ <xsl:template match="om:OMS[@cd='altenc' and @name='MathML_encoding']">
+ <annotation-xml encoding="MathML">
+ <xsl:value-of select="normalize-space(following-sibling::*[position()=1])"/> <!-- OMXML or OMSTR-->
+ </annotation-xml>
+ </xsl:template>
+
+ <!-- TeX_encoding -->
+ <xsl:template match="om:OMS[@cd='altenc' and @name='TeX_encoding']">
+ <annotation encoding="TeX">
+ <xsl:value-of select="normalize-space(following::om:OMSTR)"/>
+ </annotation>
+ </xsl:template>
+
+ <!-- **************************************************** -->
+ <!-- ************** Not in MathML group CDs ************* -->
+ <!-- **************************************************** -->
+
+ <!-- Everything below should not be handled by the Trivial case!) -->
+
+ <!-- Content Dictionary: linalg3 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- (column) vector -->
+ <xsl:template match="om:OMA[om:OMS[@cd='linalg3' and @name='vector']]">
+ <vector>
+ <xsl:apply-templates select="*[position()>1]"/>
+ </vector>
+ </xsl:template>
+
+ <!-- Content Dictionary: arith2 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: inverse, times -->
+
+ <!-- times -->
+ <!-- Note: This function is n-ary just like MathML! -->
+ <xsl:template match="om:OMS[@cd='arith2' and @name='times']">
+ <times/>
+ </xsl:template>
+
+ <!-- Content Dictionary: error -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- (all errors) -->
+ <xsl:template match="om:OME">
+ <mtext>
+ <xsl:text>ERROR:</xsl:text>
+ <xsl:text> Error Type: </xsl:text><xsl:value-of select="om:OMS[1]/@name"/>
+ <xsl:text> Error occured in CD: </xsl:text><xsl:value-of select="om:OMS[2]/@cd"/>
+ <xsl:text> Error occured in symbol: </xsl:text><xsl:value-of select="om:OMS[2]/@name"/>
+ </mtext>
+ </xsl:template>
+
+ <!-- Content Dictionary: moreerrors -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: algorithm, asynchronousError, encodingError, limitation,
+ unexpected -->
+
+ <!-- (all) -->
+ <xsl:template match="om:OMA[om:OMS[@cd='moreerrors']]">
+ <mtext>
+ <xsl:text>ERROR:</xsl:text>
+ <xsl:text> Error Type: </xsl:text><xsl:value-of select="normalize-space(om:OMS/@name)"/>
+ <xsl:text> Description: </xsl:text><xsl:value-of select="normalize-space(om:OMSTR)"/>
+ </mtext>
+ </xsl:template>
+
+ <!-- Content Dicitionary: transc3 -->
+ <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
+
+ <!-- This CD contains: arccos, arccosh, arccot, arccoth, arccsc, arccsch,
+ arcsec, arcsech, arcsin, arcsinh, arctan, arctanh, ln, log -->
+
+ <!-- (all except log) -->
+ <xsl:template match="om:OMS[@cd='transc3']">
+ <xsl:element name="{@name}"/>
+ </xsl:template>
+
+ <!-- log -->
+ <xsl:template match="om:OMA[om:OMS[@cd='transc3' and @name='log']]">
+ <apply>
+ <log/>
+ <logbase>
+ <xsl:apply-templates select="*[3]"/>
+ </logbase>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </xsl:template>
+
+ <!-- **************************************************** -->
+ <!-- **************** EVERYTHING ELSE ******************* -->
+ <!-- **************************************************** -->
+
+ <!-- Note: Rather than hard code all of the CDs, I just assign the lowest
+ priority among all templates. -->
+
+ <xsl:template match="om:OMS[@cd and @name]" priority="-10">
+ <csymbol>
+ <xsl:attribute name="definitionURL">
+ <xsl:value-of select="concat(concat(concat('http://www.openmath.org/cd/',@cd),'#'),@name)"/>
+ </xsl:attribute>
+ </csymbol>
+ </xsl:template>
+
+ <!-- **************************************************** -->
+ <!-- **************** HELPER TEMPLATES ****************** -->
+ <!-- **************************************************** -->
+
+ <!-- All mode "convert" templates are for converting OMSs or OMIs to
+ numbers including in various cn containing <sep/> -->
+
+ <xsl:template match="om:OMS[@cd='alg1' and @name='zero']" mode="convert">0</xsl:template>
+
+ <xsl:template match="om:OMS[@cd='alg1' and @name='one']" mode="convert">1</xsl:template>
+
+ <xsl:template match="om:OMS" mode="convert">
+ <xsl:choose>
+ <xsl:when test="@name='pi'">&pi;</xsl:when>
+ <xsl:when test="@name='i'">&ii;</xsl:when>
+ <xsl:when test="@name='NaN'">&NaN;</xsl:when>
+ <xsl:when test="@name='gamma'">&gamma;</xsl:when>
+ <xsl:when test="@name='e'">&ee;</xsl:when>
+ <xsl:when test="@name='true'">&true;</xsl:when>
+ <xsl:when test="@name='false'">&false;</xsl:when>
+ <xsl:when test="@name='infinity'">&infin;</xsl:when>
+ <xsl:otherwise><xsl:value-of select="normalize-space(.)"/></xsl:otherwise> <!-- for debugging -->
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="om:OMI" mode="convert">
+ <xsl:variable name="x" select="normalize-space(.)"/>
+ <xsl:choose>
+ <xsl:when test="contains($x,'x')">
+ <xsl:value-of select="concat(substring-before($x,'x'),substring-after($x,'x'))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$x"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="om:OMF" mode="convert">
+ <xsl:value-of select="@*"/>
+ </xsl:template>
+
+ <!-- The following templates, with mode "map" and "suchthat", are used to contruct sets or lists
+ without enumerating every element -->
+
+ <xsl:template match="om:OMA" mode="map">
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="2"/>
+ </xsl:apply-templates>
+ </bvar>
+ <condition>
+ <apply>
+ <in/>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="2"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="*[3]"/>
+ </apply>
+ </condition>
+ <xsl:apply-templates select="*[2]"/>
+ </xsl:template>
+
+ <xsl:template match="om:OMA" mode="suchthat">
+ <bvar>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="3"/>
+ </xsl:apply-templates>
+ </bvar>
+ <condition>
+ <apply>
+ <and/>
+ <xsl:apply-templates select="*[3]"/>
+ <apply>
+ <in/>
+ <xsl:apply-templates select="." mode="getVar">
+ <xsl:with-param name="NUM" select="3"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="*[2]"/>
+ </apply>
+ </apply>
+ </condition>
+ </xsl:template>
+
+ <!-- This template is for getting bound variables (all variables in <OMBIND>) -->
+ <!-- Note: Default bound variable is "x" -->
+
+ <xsl:template match="om:OMA" mode="getVar">
+ <xsl:param name="NUM" select="3"/>
+ <xsl:choose>
+ <xsl:when test="*[$NUM]=om:OMBIND">
+ <xsl:apply-templates select="*[$NUM]/om:OMBVAR/om:OMV[position()>0]"/>
+ </xsl:when>
+ <xsl:otherwise> <!-- default -->
+ <ci>x</ci>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Added by Hans Hagen -->
+
+ <xsl:template match="om:OMS[@cd='altenc' and @name='TeX_encoding']">
+ <annotation encoding="TeX">
+ <xsl:value-of select="normalize-space(following::om:OMSTR)"/>
+ </annotation>
+ </xsl:template>
+
+ <xsl:template match="om:OMS[(@cd='math4all' or @cd='mathadore' or @cd='m4all') and @name]">
+ <csymbol>
+ <xsl:attribute name="definitionURL">
+ <xsl:value-of select="concat(concat('http://www.openmath.org/cd/mathadore','#'),@name)"/>
+ </xsl:attribute>
+ </csymbol>
+ </xsl:template>
+
+<!--
+ <xsl:template match="om:OMS[@cd='mathadore' and @name]">
+ <csymbol>
+ <xsl:attribute name="definitionURL">
+ <xsl:value-of select="concat(concat(@cd,'#'),@name)"/>
+ </xsl:attribute>
+ </csymbol>
+ </xsl:template>
+-->
+
+ <xsl:template match="om:OMA[om:OMS[@cd='combinat1' and @name='binomial']]">
+ <matrix>
+ <matrixrow><xsl:apply-templates select="*[2]"/></matrixrow>
+ <matrixrow><xsl:apply-templates select="*[3]"/></matrixrow>
+ </matrix>
+ </xsl:template>
+
+ <!-- <OMS cd="units_siprefix1" name="centi" cdbase="mathadore"/> -->
+ <!-- <OMS cd="units_metric1" name="metre" cdbase="mathadore"/> -->
+
+ <xsl:template match="om:OMS[contains(@cd,'units_')]">
+ <csymbol>
+ <xsl:attribute name="definitionURL">
+ <xsl:value-of select="concat(concat(concat(concat(
+ 'http://www.openmath.org/cd/mathadore','#'),@cd),'@'),@name)"/>
+ </xsl:attribute>
+ </csymbol>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tex/context/modules/mkii/x-openmath.mkii b/tex/context/modules/mkii/x-openmath.mkii
new file mode 100644
index 000000000..38474996e
--- /dev/null
+++ b/tex/context/modules/mkii/x-openmath.mkii
@@ -0,0 +1,4 @@
+% This module is yet empty. We assume a transformation using
+% x-openmath.xsl.
+
+\endinput
diff --git a/tex/context/modules/mkii/x-openmath.xsl b/tex/context/modules/mkii/x-openmath.xsl
new file mode 100644
index 000000000..ffb404939
--- /dev/null
+++ b/tex/context/modules/mkii/x-openmath.xsl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="xml"/>
+
+ <!-- newline, temp hack, latest texexec handles it okay -->
+
+ <xsl:template match="processing-instruction()"><xsl:copy/><xsl:text>
+ </xsl:text></xsl:template>
+
+ <!-- xsl:template match="*"><xsl:copy/></xsl:template -->
+ <!-- xsl:element name="{name(current())}"><xsl:apply-templates/></xsl:element -->
+
+<!--
+ <xsl:template match="*">
+ <xsl:copy>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+-->
+
+ <xsl:template match="node()|@*" >
+ <xsl:copy>
+ <xsl:apply-templates select = "node()|@*" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment"></xsl:template>
+
+ <xsl:variable name='openmath-to-content-mathml'><value-of select='$stylesheet-path'/>/x-openmath.xsl</xsl:variable>
+
+ <xsl:include href="x-om2cml.xsl"/>
+
+</xsl:stylesheet>
diff --git a/tex/context/modules/mkii/x-physml.mkii b/tex/context/modules/mkii/x-physml.mkii
new file mode 100644
index 000000000..4d9cffe33
--- /dev/null
+++ b/tex/context/modules/mkii/x-physml.mkii
@@ -0,0 +1,16 @@
+%D \module
+%D [ file=m-physml,
+%D version=2001.09.04,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Loading PHYSML Filters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[units] \useXMLfilter[pml,pmu]
+
+\endinput
diff --git a/tex/context/modules/mkii/x-physml.xsd b/tex/context/modules/mkii/x-physml.xsd
new file mode 100644
index 000000000..865d88c58
--- /dev/null
+++ b/tex/context/modules/mkii/x-physml.xsd
@@ -0,0 +1,172 @@
+<?xml version="1.0"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ This schema covers (basic presentational) Physics
+ markup. It combines the power of MathML and the ConTeXt
+ units engine.
+
+ author: Hans Hagen, copyright: PRAGMA-ADE / Hasselt NL
+ </xsd:documentation>
+</xsd:annotation>
+
+<xsd:complexType name="unit.power.type">
+ <xsd:element name="Inverse" minOccurs="0" maxOccurs="1" />
+ <xsd:choice>
+ <xsd:element name="Linear" />
+ <xsd:element name="Square" />
+ <xsd:element name="Cubic" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="unit.prefix.type">
+ <xsd:choice>
+ <xsd:element name="Atto" />
+ <xsd:element name="Femto" />
+ <xsd:element name="Pico" />
+ <xsd:element name="Nano" />
+ <xsd:element name="Micro" />
+ <xsd:element name="Milli" />
+ <xsd:element name="Centi" />
+ <xsd:element name="Deci" />
+ <xsd:element name="Hecto" />
+ <xsd:element name="Kilo" />
+ <xsd:element name="Mega" />
+ <xsd:element name="Giga" />
+ <xsd:element name="Terra" />
+ <xsd:element name="Peta" />
+ <xsd:element name="Exa" />
+
+ <xsd:element name="NoUnit" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="unit.midfix.type">
+ <xsd:choice>
+ <xsd:element name="Per" />
+ <xsd:element name="Times" />
+ <xsd:element name="Solidus" />
+ <xsd:element name="OutOf" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="unit.suffix.type">
+ <xsd:choice>
+ <xsd:element name="Ampere" />
+ <xsd:element name="Angstrom" />
+ <xsd:element name="At" />
+ <xsd:element name="Atm" />
+ <xsd:element name="Atom" />
+ <xsd:element name="Bar" />
+ <xsd:element name="Baud" />
+ <xsd:element name="Bell" />
+ <xsd:element name="Bequerel" />
+ <xsd:element name="Bit" />
+ <xsd:element name="Byte" />
+ <xsd:element name="Cal" />
+ <xsd:element name="Candela" />
+ <xsd:element name="Celsius" />
+ <xsd:element name="Coulomb" />
+ <xsd:element name="Day" />
+ <xsd:element name="Deg" />
+ <xsd:element name="Degrees" />
+ <xsd:element name="Equivalent" />
+ <xsd:element name="EVolt" />
+ <xsd:element name="eVolt" />
+ <xsd:element name="Fahrenheit" />
+ <xsd:element name="Farad" />
+ <xsd:element name="Foot" />
+ <xsd:element name="Force" />
+ <xsd:element name="Gauss" />
+ <xsd:element name="Gram" />
+ <xsd:element name="Gray" />
+ <xsd:element name="Henry" />
+ <xsd:element name="Hertz" />
+ <xsd:element name="Hour" />
+ <xsd:element name="Inch" />
+ <xsd:element name="Joule" />
+ <xsd:element name="Kelvin" />
+ <xsd:element name="Liter" />
+ <xsd:element name="Lux" />
+ <xsd:element name="Meter" />
+ <xsd:element name="Min" />
+ <xsd:element name="Mol" />
+ <xsd:element name="Molair" />
+ <xsd:element name="Month" />
+ <xsd:element name="Newton" />
+ <xsd:element name="Ohm" />
+ <xsd:element name="Pascal" />
+ <xsd:element name="Rad" />
+ <xsd:element name="RevPerMin" />
+ <xsd:element name="RevPerSec" />
+ <xsd:element name="Sec" />
+ <xsd:element name="Second" />
+ <xsd:element name="Siemens" />
+ <xsd:element name="Sievert" />
+ <xsd:element name="Sterant" />
+ <xsd:element name="Tesla" />
+ <xsd:element name="Volt" />
+ <xsd:element name="VoltAC" />
+ <xsd:element name="VoltDC" />
+ <xsd:element name="Watt" />
+ <xsd:element name="Weber" />
+ <xsd:element name="Week" />
+ <xsd:element name="Year" />
+
+ <xsd:element name="Unit" />
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:complexType name="unit.component.type">
+ <xsd:sequence>
+ <xsd:element ref="unit.power.type" minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="unit.prefix.type" minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="unit.suffix.type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="unit.type">
+ <xsd:choice>
+ <xsd:sequence>
+ <xsd:element ref="unit.component.type" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:element ref="unit.component.type" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="unit.midfix.type" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="unit.component.type" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:choice>
+</xsd:complexType>
+
+<xsd:element name="unit" type="unit.type" />
+
+<xsd:element name="physics.type">
+ <choice>
+ <xsd:element name="apply">
+ <xsd:sequence>
+ <xsd:element name="unit" minOccurs="1" maxOccurs="1" />
+ <xsd:element name="some kind of mml result" minOccurs="0" maxOccurs="1" />
+ <choice>
+ <xsd:element name="cu" type=unit.type minOccurs="0" maxOccurs="1" />
+ <xsd:element name="cunseq" type=unit.type minOccurs="0" maxOccurs="1" />
+ <xsd:element name="csymbol" type=unit.type minOccurs="0" maxOccurs="1" />
+ </choice>
+ </xsd:sequence>
+ </xsd:element>
+ <xsd:sequence>
+ <choice>
+ <xsd:element name="cn" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="ci" minOccurs="0" maxOccurs="1" />
+ </choice>
+ <xsd:element name="cu" type="unit.type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </choice>
+</xsd:element>
+
+<xsd:element name="phys" type="physics.type" />
+<xsd:element name="iphys" type="physics.type" />
+<xsd:element name="dphys" type="physics.type" />
+
+</xsd:schema>
diff --git a/tex/context/modules/mkii/x-res-00.mkii b/tex/context/modules/mkii/x-res-00.mkii
new file mode 100644
index 000000000..d031e1453
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-00.mkii
@@ -0,0 +1,67 @@
+%D \module
+%D [ file=x-res-00,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Libraries,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+% \defineXMLcommandpush [rl:instance] (todo)
+% \rawframed == [frame=off,offset=overlay]
+
+% resource library
+
+\defineXMLprocess [rl:figurelibrary] % not to be used any longer
+\defineXMLprocess [rl:library]
+
+% resource library description
+
+\defineXMLignore [rl:description]
+
+\defineXMLpush [rl:organization]
+\defineXMLpush [rl:product]
+\defineXMLpush [rl:project]
+\defineXMLpush [rl:collection]
+
+% resource library entries (better use XMLignore)
+
+\defineXMLignore [rl:applet]
+\defineXMLignore [rl:application]
+\defineXMLignore [rl:figure]
+\defineXMLignore [rl:movie]
+\defineXMLignore [rl:sound]
+
+\defineXMLpush [rl:type]
+\defineXMLpush [rl:state]
+\defineXMLpush [rl:width]
+\defineXMLpush [rl:height]
+\defineXMLpush [rl:file]
+\defineXMLpush [rl:label]
+\defineXMLpush [rl:original]
+\defineXMLpush [rl:title]
+\defineXMLpush [rl:alternative]
+\defineXMLpush [rl:dummy]
+\defineXMLpush [rl:icon]
+\defineXMLpush [rl:copyright]
+\defineXMLpush [rl:comment]
+\defineXMLpush [rl:status]
+\defineXMLpush [rl:original]
+\defineXMLpush [rl:manipulation]
+
+% instances
+
+\defineXMLignore [rl:instance]
+
+\defineXMLpush [rl:background]
+\defineXMLpush [rl:viewport]
+\defineXMLpush [rl:dimension]
+\defineXMLpush [rl:position]
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-res-01.mkii b/tex/context/modules/mkii/x-res-01.mkii
new file mode 100644
index 000000000..41580a0b8
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-01.mkii
@@ -0,0 +1,487 @@
+%D \module
+%D [ file=x-fig-01,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D See \type {x-fig-00.tex} and \type {x-fig-04.tex} for more
+%D information on how to use and generate figure databases.
+%D This file loads the file named \type {\jobfilename}
+%D (\TEXEXEC\ will set this variable). You can apply this
+%D style to a database by saying:
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-make yourfile.xml
+%D \stoptyping
+%D
+%D The following modes are supported:
+%D
+%D \starttabulate[|lT|l|]
+%D \NC letter \NC map the preview on letter size \NC \NR
+%D \NC compact \NC use an alternative presentation \NC \NR
+%D \NC clipgrid-distance \NC add a copy with grid overlayed \NC \NR
+%D \NC clipgrid-steps \NC add a copy with grid overlayed \NC \NR
+%D \NC previewpage-A4 \NC show graphic relative to A4 \NC \NR
+%D \NC previewpage-letter \NC show graphic relative to letter \NC \NR
+%D \NC previewpage-S6 \NC show graphic relative to S6 \NC \NR
+%D \stoptabulate
+%D
+%D The resulting file has the following characteristics:
+%D
+%D \startitemize[packed]
+%D \item the document is split into three sections: first each
+%D figure is shown at its own page, then an overview of
+%D figures is shown with some data alongside, and
+%D finally an index and table of contents shows up
+%D \item there is no title page, which means that one can
+%D access a figure by page number without offset
+%D \item the document is opened at the first overview page,
+%D that is, when the viewer supports it
+%D \item the graphic is shown 3~times: on a page of its own,
+%D scaled to a fixed dimension, and relative to a4 or
+%D letter paper size
+%D \item the labels can be accessed in an index and list at
+%D the end of the document
+%D \stopitemize
+%D
+%D We use named destinations, which means that one can
+%D access a figure by name from an external application.
+
+\usemodule[res-00]
+
+\autoXMLnamespace[rl]
+
+\setupoutput[pdftex] \overcomePDFspacefalse
+
+\setjobfullname {xml} % default suffix
+
+\doifnothing {\jobfullname} {\end}
+\doiffileelse {\jobfullname} {} {\end}
+
+\definesymbol [attachment] [{\bf\color[darkred]{\jobname.xml}}]
+\setupattachments [symbol=attachment]
+\useattachment [datafile] [\jobname.xml]
+
+\def\StartDescription
+ {\bgroup}
+
+\def\StopDescription
+ {\subject {Figure collection}
+ \starttabulate[|lBe|p|]
+ \doifXMLdataelse{rl:organization}
+ {\NC organization \NC \XMLflush{rl:organization} \NC \NR}{}
+ \doifXMLdataelse{rl:project}
+ {\NC project \NC \XMLflush{rl:project} \NC \NR}{}
+ \doifXMLdataelse{rl:product}
+ {\NC product \NC \XMLflush{rl:product} \NC \NR}{}
+ \doifXMLdataelse{rl:comment}
+ {\NC comment \NC \XMLflush{rl:comment} \NC \NR}{}
+ \NC specification \NC \attachment[datafile] \NC \NR
+ \stoptabulate
+ \blank[2*big]
+ \egroup}
+
+
+\def\localexternalfigurereplacement#1#2#3% hack, no reuse of dummies (yet), todo: pass objname
+ {\doifelsenothing{\XMLflush{rl:label}}
+ {\edef\FigureName{\XMLflush{rl:label}}}
+ {\edef\FigureName{\XMLflush{rl:file}}}%
+ \doifobjectfoundelse{rl}\FigureName
+ {}
+ {\setobject{rl}\FigureName\vbox{\normalexternalfigurereplacement{#1}{#2}{#3}}}%
+ \getobject{rl}\FigureName}
+
+\startmode[dummy]
+
+ \useMPlibrary[dum]
+
+ \def\StartFigureA
+ {\bgroup
+ \XMLassign{rl:file}{dummy}}
+
+ \let\normalexternalfigurereplacement\externalfigurereplacement
+ \let\externalfigurereplacement \localexternalfigurereplacement
+
+\stopmode
+
+\startnotmode[dummy]
+
+ \def\StartFigureA
+ {\bgroup
+ \XMLassign{rl:file}{unknown}}
+
+\stopnotmode
+
+\startbuffer[unknown]
+ \framed
+ [width=\XMLpar{rl:dummy}{width}{12cm},
+ height=\XMLpar{rl:dummy}{height}{8cm},
+ background=color,
+ backgroundcolor=gray,
+ foregroundcolor=darkred,
+ align={lohi,middle}, % normal,
+ frame=off]
+ {\bf \XMLflush{rl:dummy}}
+\stopbuffer
+
+\useexternalfigure[unknown][unknown][type=buffer,object=no]
+
+\defineoverlay[page][\overlaybutton{Description}]
+
+% \def\externalfigurereplacement#1#2#3%
+% {\getbuffer[rl-unknown]}
+
+\def\StopFigureA
+ {\doglobal\increment\CurrentPage
+ \setupbackgrounds[page][background=page]
+ \doifelsenothing{\XMLflush{rl:label}}
+ {\expanded{\definereference[Description][about:\XMLflush{rl:file}]}%
+ \expanded{\pagereference[\XMLflush{rl:file}]}}
+ {\expanded{\definereference[Description][about:\XMLflush{rl:label}]}%
+ \expanded{\pagereference[\XMLflush{rl:label}]}}
+ \pagefigure[\XMLflush{rl:file}]
+ \setupbackgrounds[page][background=]
+ \egroup}
+
+\def\StartFigureB
+ {\StartFigureA}
+
+\defineregister
+ [figureindex]
+ [figureindices]
+
+\setupregister
+ [figureindex]
+ [ownnumber=yes,
+ criterium=text,
+ interaction=text,
+ indicator=no]
+
+\definelist
+ [figurelist]
+
+\setuplist
+ [figurelist]
+ [criterium=text,
+ pagenumber=no,
+ width=2em,
+ interaction=all]
+
+\setupcolors
+ [state=start]
+
+\setuptolerance
+ [verytolerant]
+
+% Ulgy:
+
+\startmode[letter] % downward compatible
+ \enablemode[previewpage-letter]
+\stopmode
+
+\startnotmode[previewpage-letter,previewpage-S6]
+ \enablemode[previewpage-A4]
+\stopnotmode
+
+\startsetups[paper]
+\startmode[previewpage-A4]
+ \framed
+ [width=210mm,height=297mm,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLflush{rl:file}][reset=yes]}
+\stopmode
+\startmode[previewpage-letter]
+ \framed
+ [width=8.5in,height=11in,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLflush{rl:file}][reset=yes]}
+\stopmode
+\startmode[previewpage-S6]
+ \framed
+ [width=600pt,height=450pt,offset=overlay,frame=off,
+ background=color,backgroundcolor=white]
+ {\externalfigure[\XMLflush{rl:file}][reset=yes]}
+\stopmode
+\stopsetups
+
+\setupbuttons
+ [offset=10pt,
+ width=broad,
+ strut=no,
+ rulethickness=1pt,
+ framecolor=darkred]
+
+\definecolor[XMLRLcolor][white]
+
+\def\StopFigureB
+ {\doglobal\increment\CurrentPage
+ \doifelsenothing{\XMLflush{rl:label}}
+ {\expanded{\definereference[Figure][\XMLflush{rl:file}]}%
+ \expanded{\definereference[GridPg][grid:\XMLflush{rl:file}]}}
+ {\expanded{\definereference[Figure][\XMLflush{rl:label}]}%
+ \expanded{\definereference[GridPg][grid:\XMLflush{rl:label}]}}%
+ \button
+ {\hbox to \hsize
+ {\forgetall \dontcomplain
+ \doifelsenothing{\XMLflush{rl:label}}
+ {\expanded{\pagereference[about:\XMLflush{rl:file}]}}
+ {\expanded{\pagereference[about:\XMLflush{rl:label}]}}%
+ % moved here, because descriptions may be absent
+ \ifnum\CurrentPage=1 \pagereference[begin]\fi
+ %
+ \expanded{\writetolist[figurelist]{\CurrentPage}{\XMLflush{rl:label}}}%
+ \expanded{\figureindex{\CurrentPage}{\XMLflush{rl:label}}}%
+ \startnotmode[compact]%
+ \vbox to 100pt
+ {\hsize30pt
+ \vskip5pt
+ \hbox to \hsize{\hss\strut\bf\CurrentPage\hss}%
+ \vfill}%
+ \advance\hsize by -30pt
+ \stopnotmode
+ \startmode[compact]%
+ \advance\hsize by -10pt
+ \hskip10pt
+ \stopmode
+ \button % \framed
+ [width=150pt,height=100pt,offset=10pt,frame=off,
+ background=color,backgroundcolor=white,color=]
+ {\externalfigure
+ [\XMLflush{rl:file}]
+ %[maxheight=80pt,frame=off,maxwidth=130pt,factor=max]}%
+ [factor=max]}%
+ [GridPg]%
+ \let\FigWid\figurenaturalwidth
+ \let\FigHei\figurenaturalheight
+ \advance\hsize by -150pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt
+ {\hsize40pt
+ %\externalfigure
+ % [paper]
+ % [type=buffer,frame=on,
+ % framecolor=darkred,rulethickness=.5pt,
+ % width=40pt,object=no]
+ \framed
+ [offset=overlay,
+ framecolor=darkred,
+ rulethickness=.5pt]
+ {\scale[width=40pt]{\setups[paper]}}%
+ \startmode[compact]%
+ \vfill
+ \hbox to \hsize{\hss\strut\bf\CurrentPage\hss}%
+ \stopmode
+ \vfill}%
+ \advance\hsize by -40pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt
+ {\blank[disable]
+ \starttabulate[|Bel|p|]
+ \NC file \NC \XMLflush{rl:file} \NC \NR
+ \doifXMLdata{rl:label}
+ {\NC label \NC \XMLflush{rl:label} \NC \NR}
+ \NC w$\times$h \NC \FigWid$\times$\FigHei \NC \NR
+ \doifXMLdata{rl:copyright}
+ {\NC copyright \NC \XMLflush{rl:copyright} \NC \NR}
+ \doifXMLdata{rl:status}
+ {\doifelse{\XMLflush{rl:status}}{obsolete}
+ {\NC status \NC \dontleavehmode \color[darkred]{\bf\XMLflush{rl:status}} \NC \NR}
+ {\NC status \NC \XMLflush{rl:status} \NC \NR}}
+ \doifXMLdata{rl:comment}
+ {\NC comment \NC \XMLflush{rl:comment} \NC \NR}
+ \stoptabulate
+ \vfill}}}%
+ [Figure]
+ \vskip10pt
+ \egroup}
+
+\def\StartFigureC
+ {\StartFigureA}
+
+\def\StopFigureC
+ {\doglobal\increment\NumberOfFigures
+ \egroup}
+
+\setuplayout
+ [topspace=15pt,backspace=15pt,
+ header=0pt,footer=0pt,bottom=20pt,bottomdistance=10pt,
+ width=middle,height=fit]
+
+\setupbackgrounds
+ [page]
+ [background=,
+ backgroundcolor=gray]
+
+\setupinteractionscreen
+ [width=max,
+ height=max]
+
+\setupcolors
+ [state=start]
+
+\setupinteraction
+ [style=,
+ color=,
+ contrastcolor=,
+ state=start]
+
+\setuphead
+ [section]
+ [style=bfb]
+
+% \setupbodyfont
+% [pos]
+
+\setupinteractionmenu
+ [bottom]
+ [left=\hfill,
+ middle=\hskip10pt,
+ frame=off,
+ style=bold,
+ background=color,
+ backgroundcolor=darkred,
+ foregroundcolor=white]
+
+\startinteractionmenu[bottom]
+ \but [begin] begin \\
+ \but [index] index \\
+ \but [list] list \\
+ \but [CloseDocument] close \\
+ \but [PreviousJump] go back \\
+\stopinteractionmenu
+
+\setupinteraction
+ [openaction=begin]
+
+\defineXMLenvironment [rl:figurelibrary] \StartLibrary \StopLibrary
+\defineXMLenvironment [rl:library] \StartLibrary \StopLibrary
+
+\starttext
+
+\def\StartLibrary{\mainlanguage[\XMLpar{rl:library}{language}{en}]}
+\def\StopLibrary {}
+
+\defineXMLignore [rl:description]
+\defineXMLenvironment [rl:figure] \StartFigureC \StopFigureC
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfullname}
+
+\increment\NumberOfFigures
+
+\defineXMLignore [rl:description]
+\defineXMLenvironment [rl:figure] \StartFigureA \StopFigureA
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfullname}
+
+\setuppapersize
+ [S6][S6]
+
+\setupbackgrounds
+ [page]
+ [background=color]
+
+\setupinteraction
+ [menu=on]
+
+\defineXMLenvironment [rl:description] \StartDescription \StopDescription
+\defineXMLenvironment [rl:figure] \StartFigureB \StopFigureB
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfullname} \page
+
+\subject [list] {List of figures}
+
+\placelist[figurelist] \page
+
+\subject [index] {Index of figures}
+
+\startcolumns
+\placeregister[figureindex]
+\stopcolumns
+
+\doifmodeelse{clipgrid-distance,clipgrid-steps}{\page}{\stoptext}
+
+\startuniqueMPgraphic{clipgrid}{dx,dy,nx,ny,type}
+ numeric gdx, gdy, lbx, lby ;
+ if \MPvar{type}=1 :
+ gdx := \MPvar{dy} ;
+ gdy := \MPvar{dx} ;
+ else :
+ gdx := OverlayWidth /\MPvar{nx} ;
+ gdy := OverlayHeight/\MPvar{ny} ;
+ fi ;
+ lbx := gdx ;
+ lby := gdy ;
+ defaultfont := "\truefontname{Mono}" ;
+ defaultscale := .5 ;
+ numeric pen ; pen := .25pt ;
+ def MyGrid text t =
+ draw vlingrid (0,OverlayWidth ,gdy,OverlayWidth ,OverlayHeight) t ;
+ draw hlingrid (0,OverlayHeight,gdx,OverlayHeight,OverlayWidth ) t ;
+ enddef ;
+ pickup pencircle scaled pen ;
+ MyGrid withcolor white ;
+ MyGrid dashed evenly scaled pen ;
+ draw OverlayBox withcolor white ;
+ draw OverlayBox dashed evenly scaled pen ;
+ draw vlinlabel.bot(0,eps+OverlayWidth /lby,2,OverlayWidth ) ;
+ draw hlinlabel.lft(0,eps+OverlayHeight/lbx,2,OverlayHeight) ;
+ setbounds currentpicture to OverlayBox enlarged (2*EmWidth) ;
+\stopuniqueMPgraphic
+
+\presetMPvariable[clipgrid][dx=10pt]
+\presetMPvariable[clipgrid][dy=10pt]
+\presetMPvariable[clipgrid][nx=10]
+\presetMPvariable[clipgrid][ny=10]
+
+\startmode[clipgrid-distance]
+ \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=1}]
+\stopmode
+
+\startmode[clipgrid-steps]
+ \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=2}]
+\stopmode
+
+\setupexternalfigures
+ [background={color,foreground,grid},
+ backgroundcolor=white]
+
+\def\StartFigureD
+ {\StartFigureA}
+
+\def\StopFigureD
+ {\doglobal\increment\CurrentPage
+ \setupbackgrounds[page][background=page]
+ \startpagefigure[\XMLflush{rl:file}][offset=20pt]%
+ \doifelsenothing{\XMLflush{rl:label}}
+ {\expanded{\definereference[Description][about:\XMLflush{rl:file}]}%
+ \expanded{\pagereference[grid:\XMLflush{rl:file}]}}
+ {\expanded{\definereference[Description][about:\XMLflush{rl:label}]}%
+ \expanded{\pagereference[grid:\XMLflush{rl:label}]}}
+ \stoppagefigure
+ %\pagefigure[\XMLflush{rl:file}][offset=20pt]
+ \setupbackgrounds[page][background=]
+ \egroup}
+
+\defineXMLignore [rl:description]
+\defineXMLenvironment [rl:figure] \StartFigureD \StopFigureD
+
+\doglobal\newcounter\CurrentPage
+
+\processXMLfilegrouped{\jobfullname} \page
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-res-02.mkii b/tex/context/modules/mkii/x-res-02.mkii
new file mode 100644
index 000000000..f8502dbac
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-02.mkii
@@ -0,0 +1,72 @@
+%D \module
+%D [ file=x-res-02,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Inclusion (I),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module enables non||\ConTeXt\ users to access the
+%D database. For this, you need to run
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-fake yourfile.xml
+%D \stoptyping
+%D
+%D The resulting file, \type {yourfile.fig}, can be loaded
+%D in the normal way. The figures can be accessed with:
+%D
+%D \starttyping
+%D \getfigurefile{label}
+%D \getfigurepage{label}
+%D \stoptyping
+%D
+%D A a bonus, the following macro is defined:
+%D
+%D \starttyping
+%D \includefigurefile width 10cm {label}
+%D \stoptyping
+
+\usemodule[res-00]
+
+\doifnothing {\jobfullname} {\end}
+\doiffileelse {\jobfullname} {} {\end}
+
+\defineXMLenvironment [rl:figurelibrary] \StartLibrary \StopLibrary
+\defineXMLenvironment [rl:library] \StartLibrary \StopLibrary
+\defineXMLenvironment [rl:figure] \StartFigure \StopFigure
+
+\def\StartLibrary
+ {\immediate\openout \scratchwrite=\jobfilename.fig
+ \immediate\write\scratchwrite{\string\input\space x-fig-03.tex \string\relax}
+ \immediate\write\scratchwrite{}}
+
+\def\StopLibrary
+ {\immediate\write\scratchwrite{}
+ \immediate\write\scratchwrite{\string\endinput}
+ \immediate\closeout\scratchwrite}
+
+\def\StartFigure
+ {\bgroup}
+
+\def\StopFigure
+ {\doglobal\increment\CurrentPage
+ \immediate\write\scratchwrite
+ {\string\setfiguredata\space
+ {\XMLpop{rl:label}}
+ {\jobfilename}
+ {\CurrentPage}}
+ \egroup}
+
+\doglobal\newcounter\CurrentPage
+
+\starttext
+
+\processXMLfilegrouped{\jobfullname}
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-res-03.mkii b/tex/context/modules/mkii/x-res-03.mkii
new file mode 100644
index 000000000..15f2620c1
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-03.mkii
@@ -0,0 +1,44 @@
+%D \module
+%D [ file=x-fig-03,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Inclusion (II),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifx \undefined \convertMPtoPDF \input supp-pdf.tex \fi
+\ifx \undefined \includefigurefile \else \expandafter \endinput \fi
+
+\gdef\getfigurefile#1%
+ {\expandafter\ifx\csname x-fig-f-#1\endcsname\relax
+ \currentfigurefile
+ \else
+ \csname x-fig-f-#1\endcsname
+ \fi}
+
+\gdef\getfigurepage#1%
+ {\expandafter\ifx\csname x-fig-p-#1\endcsname\relax
+ 1%
+ \else
+ \csname x-fig-p-#1\endcsname
+ \fi}
+
+\gdef\setfiguredata#1#2#3%
+ {\gdef\currentfigurefile{#2}%
+ \expandafter\gdef\csname x-fig-f-#1\endcsname{#2}%
+ \expandafter\gdef\csname x-fig-p-#1\endcsname{#3}}
+
+\def\includefigurefile#1#%
+ {\doincludefigurefile{#1}}
+
+\def\doincludefigurefile#1#2%
+ {\edef\next{\noexpand\pdfimage
+ #1 page \getfigurepage{#2} {\getfigurefile{#2}.pdf}}%
+ \next}
+
+\endinput
diff --git a/tex/context/modules/mkii/x-res-04.mkii b/tex/context/modules/mkii/x-res-04.mkii
new file mode 100644
index 000000000..b22e9ffa4
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-04.mkii
@@ -0,0 +1,336 @@
+%D \module
+%D [ file=x-fig-04,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Loading,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% hele base laden
+
+\setXMLfallbackmode3
+
+% icon : preview
+% caption : \figurebasevariable{caption}
+% background : rgb cmyk gray name
+% dimensions : width height offset (l,r,t,b) area
+% alternative : tag label / evt list
+%
+% movie
+% sound
+% applet
+% application
+
+\usemodule[res-00] % basic element definitions
+
+%D This module implements an interface to a figure database
+%D and file. The database is formatted in \XML\ conforming
+%D the following \DTD:
+%D
+%D \typefile{x-fig-00.dtd}
+%D
+%D A figure base coded this way looks like:
+%D
+%D \starttyping
+%D <!-- texexec --pdf --use=fig-01 figtest.xml -->
+%D
+%D <?xml version='1.0'?>
+%D
+%D <rl:library language="nl">
+%D
+%D <rl:description>
+%D <organization>PRAGMA Advanced Document Engineering</rl:organization>
+%D <project>Manuals</rl:project>
+%D <product>Beginners Manual</rl:product>
+%D <comment>A bunch of figures.</rl:comment>
+%D </rl:description>
+%D
+%D <rl:figure>
+%D <rl:file>koe.pdf</rl:file>
+%D <rl:label>a dutch cow</rl:label>
+%D <rl:copyright>Corel Draw Suite</rl:copyright>
+%D <rl:comment>I bet that you've seen this cow before.</rl:comment>
+%D </rl:figure>
+%D
+%D <rl:figure>
+%D <rl:dummy width="4cm" height="3cm">non existent</rl:dummy>
+%D <rl:label>a european cow</rl:label>
+%D <rl:copyright>Nobody</rl:copyright>
+%D <rl:comment>When will we talk about European cows?</rl:comment>
+%D </rl:figure>
+%D
+%D </rl:library>
+%D \stoptyping
+%D
+%D You can convert this base into a \PDF\ file using
+%D \TEXEXEC\ and another module in this suite.
+%D
+%D \starttyping
+%D texexec --pdf --use=fig-make yourfile.xml
+%D \stoptyping
+%D
+%D You can now select a graphic from this file using the
+%D
+%D \starttyping
+%D \externalfigure[a dutch cow][width=4cm]
+%D \stoptyping
+%D
+%D This module overloads this command so that a figure is
+%D it first searched in the list of databases.
+%D
+%D \starttyping
+%D \usemodule [fig-base]
+%D \usefigurebases[yourfile]
+%D \stoptyping
+%D
+%D The special keyword \type {reset} can be used to reset
+%D this list.
+
+\startcommands dutch english
+ german czech
+ italian romanian
+
+ usefigurebase: gebruikfiguurbestand usefigurebase
+ usefigurebase usefigurebase
+ usefigurebase usefigurebase
+
+\stopcommands
+
+\unprotect
+
+\consultutilityfilefalse
+
+% 0 = no loading
+% 1 = selective loading
+% 2 = full loading
+
+\chardef\figurebasemode=1 % 2
+
+\newcounter\figurefilepage
+
+% loading a complete figure base
+
+\startXMLmapping[rl:load]
+
+\defineXMLenvironmentsave [rl:figure]
+ {\bgroup}
+ {\XMLflush{rl:figure}
+ \doglobal\increment\figurefilepage
+ \figbase@savedata{\XMLflush{rl:label}}\figurefilepage
+ \egroup}
+
+\stopXMLmapping
+
+\def\loadfigurebase#1%
+ {\doifnotflagged{rl:#1}
+ {\writestatus{figbase}{loading #1 into memory}%
+ \startnointerference
+ \autoXMLnamespace[rl]
+ \startXMLmapping[rl:load]
+ \doglobal\newcounter\figurefilepage
+ \processXMLfilegrouped{#1.xml}
+ \stopXMLmapping
+ \doglobal\setflag{rl:#1}
+ \stopnointerference}}
+
+\def\figbase@savedata#1#2%
+ {%\writestatus{figbase}{data of #1 loaded}%
+ \doglobal\saveXMLdatastructure{rl:rl:#1}{record}{page="#2"}{}{rl:figure}{}}
+
+% locating and if needed loading one figure record
+
+\startXMLmapping[rl:find]
+
+\defineXMLenvironment[rl:instance]
+ {\bgroup}
+ {\doif\askedlabel{\XMLflush{rl:label}}
+ {\doglobal\saveXMLdata{rl:g:manipulation}{rl:manipulation}%
+ \doifXMLdata{rl:original}
+ {\xdef\askedlabel{\XMLflush{rl:original}}}}%
+ \egroup}
+
+\defineXMLenvironmentsave [rl:figure]
+ {\bgroup}
+ {\XMLflush{rl:figure}
+ \doglobal\increment\figurefilepage
+ %\doshowfigurestate{base : comparing \askedlabel\space with \XMLflush{rl:label}}%
+ \doif\askedlabel{\XMLflush{rl:label}}
+ {\doshowfigurestate{base label : found \askedlabel}%
+ \ifnum\figurebasemode=\plusone % load used ones
+ \figbase@savedata\askedlabel\figurefilepage
+ \fi
+ \doglobal\saveXMLdata{rl:l:manipulation}{rl:manipulation}%
+ \xdef\figurefilelabel {\XMLflush{rl:label}}%
+ \xdef\figurefilefile {\XMLflush{rl:file}}%
+ \xdef\figurefileoriginal{\XMLflush{rl:original}}%
+ \xdef\figurefilename {\XMLflush{rl:file}}
+ \endinput}%
+ \egroup}
+
+\defineXMLenvironment [rl:record]
+ {}
+ {\xdef\figurefilename{\XMLpop{rl:file}}
+ \xdef\figurefilepage{\XMLop {page}}}
+
+\stopXMLmapping
+
+\def\getfigurefilename#1#2%
+ {\ifnum\figurebasemode=\plustwo \loadfigurebase{#1} \fi
+ \startnointerference
+ \traceXMLelementsfalse
+ \resetfigurefilebase
+ \doglobal\newcounter\figurefilepage
+ \autoXMLnamespace[rl]
+ \startXMLmapping[rl:find]
+ \xdef\figurefilebase{#1}%
+ \def\askedlabel{#2}%
+ \doifelseXMLelement{rl:rl:\askedlabel}
+ {\enableXMLelements\flushXMLelement{rl:rl:\askedlabel}}
+ {\doshowfigurestate{base path : \figurepathlist}%
+ \processcommacommand[\figurepathlist]\dogetfigurefilename}%
+ \stopXMLmapping
+ \stopnointerference}
+
+% todo: niet toegekende naam doorgeven aan calculate en pad
+% in padstring
+
+\def\dogetfigurefilename#1%
+ {\ifx\figurefilename\empty
+ \bgroup
+ \doglobal\newcounter\figurefilepage
+ \globalletempty\figurefilelabel
+ \globalletempty\figurefileoriginal
+ \globalletempty\figurefilefile
+ \xdef\figurefilebasepath{#1}%
+ \assignfullfilename{#1}{\figurefilebase}\to\filename
+ \doiffileelse{\filename.xml}
+ {\doshowfigurestate{base file : \filename}%
+ \expanded{\processXMLfilegrouped{\filename.xml}}}
+ \donothing
+ \ifx\figurefilename\empty \else
+% \global\let\figurefilebase\figurefilebase
+ \globallet\figurefilebase\filename % hm, bad omen that this is needed
+ \fi
+ \egroup
+ \fi}
+
+\newtoks\figurebaseresets
+
+\appendtoks
+ \globalletempty\figurefilebase
+ \globalletempty\figurefilename
+ \globalletempty\figurefilebasepath
+ \globalletempty\figurefilepage
+ \globalletempty\figurefilelabel
+ %\globalletempty\figurefileoriginal
+ %\globalletempty\figurefilefile
+\to\figurebaseresets
+
+\def\resetfigurefilebase
+ {\the\figurebaseresets}
+
+\ifx\doshowfigurestate\undefined \let\doshowfigurestate\gobbleoneargument \fi
+
+\def\doanalyzefiguredimensionsfromfile
+ {\ifcase\figurestatus \ifx\figurebaselist\empty \else
+ \resetfigurefilebase
+ \doshowfigurestate{base list : \figurebaselist}%
+ \processcommacommand[\figurebaselist]\dodoanalyzefiguredimensionsfromfile
+ \ifx\figurefilename\empty
+ \doshowfigurestate{base warning : no matching name found}%
+ \else
+ \doiffileelse{\figurefilebase.pdf}
+ {\doshowfigurestate{base file : \figurefilebase.pdf}%
+ \doshowfigurestate{base page : \figurefilepage}%
+ \let\figurepathlist\figurefilebasepath
+ \analyzefigurefilename{\figurefilebase.pdf}\wantedfigurelabel
+ \let\wantedfigurepage\figurefilepage}
+ {\doshowfigurestate{base missing : \figurefilebase.pdf}}
+ \fi
+ \ifcase\figurestatus
+ \analyzefigurefilename\expandedfigurename\wantedfigurelabel
+ \fi
+ \fi \fi}
+
+\def\dodoanalyzefiguredimensionsfromfile#1%
+ {\doshowfigurestate{base check : \wantedfigurename\space in #1}%
+ \getfigurefilename{#1}\wantedfigurename
+ \ifx\figurefilename\empty\else
+ \quitcommalist
+ \fi}
+
+% management
+
+% will become \useresourcelibrary
+
+\def\usefigurebase[#1]%
+ {\doifelse{#1}\v!reset
+ {\let\figurebaselist\empty}
+ {\addtocommalist{#1}\figurebaselist}}
+
+\let\figurebaselist\empty
+
+\resetfigurefilebase
+
+% manipulations / todo: fixed order
+
+\defineXMLsave [rl:manipulation]
+
+\defineXMLsingular [rl:background] [r=0,g=0,b=0,s=0,c=0,m=0,y=0,k=0]
+ {\global\setbox\foundexternalfigure\vbox
+ {\definecolor
+ [XMLRLcolor]
+ [r=\XMLop{r},g=\XMLop{g},b=\XMLop{b},s=\XMLop{s},%
+ c=\XMLop{c},m=\XMLop{m},y=\XMLop{y},k=\XMLop{k}]%
+ \framed
+ [\c!frame=\v!off,\c!offset=\v!overlay,
+ \c!background=\v!color,\c!backgroundcolor=XMLRLcolor]
+ {\box\foundexternalfigure}}}
+
+\defineXMLsingular [rl:viewport] [\??cp] % []
+ {\global\setbox\foundexternalfigure\vbox
+ {\expandXMLta \getXMLta
+ \clip
+ [\XMLta]
+ {\box\foundexternalfigure}}%
+ \global\setbox\foundexternalfigure\vbox
+ {\scale
+ [\c!width=\figurewidth,\c!height=\figureheight]
+ {\box\foundexternalfigure}}}
+
+\defineXMLsingular [rl:dimensions] [width=,height=]
+ {}
+
+\defineXMLsingular [rl:position] [offset=,width=,height=,hoffset=,voffset=]
+ {}
+
+\appendtoks
+ \doglobal\eraseXMLelement{rl:l:manipulation}%
+ \doglobal\eraseXMLelement{rl:g:manipulation}%
+\to \figurebaseresets
+
+\appendtoks
+ \startnointerference
+ \processXMLelement{rl:l:manipulation}%
+ \processXMLelement{rl:g:manipulation}%
+ \stopnointerference
+\to \externalfigurepostprocessors
+
+\protect \doifnotmode{demo}{\endinput}
+
+\starttext
+
+\setupcolors[state=start]
+
+\usefigurebase[d-fig-01]
+
+\externalfigure[part of a dutch cow][width=3cm,frame=on]
+\externalfigure[a simple dutch cow][width=5cm,frame=on]
+\externalfigure[another simple dutch cow][width=5cm,frame=on]
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-res-08.mkii b/tex/context/modules/mkii/x-res-08.mkii
new file mode 100644
index 000000000..0805f071f
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-08.mkii
@@ -0,0 +1,129 @@
+%D \module
+%D [ file=x-fig-08,
+%D version=2002.06.27,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Reporting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D TODO: make rlxtools callable from texexec (class), speeds up things.
+
+%D Experimental module!
+%D
+%D \starttyping
+%D <rl:library>
+%D <rl:usage>
+%D <rl:type>figure</rl:type>
+%D <rl:state>found|missing</rl:state>
+%D <rl:name>filename</rl:name>
+%D <rl:suffix>filesuffix</rl:suffix>
+%D <rl:width>width in pt</rl:width>
+%D <rl:height>height in pt</rl:height>
+%D <rl:comment>text</rl:comment>
+%D </rl:usage>
+%D </rl:library>
+%D \stoptyping
+
+\unprotect \doifnotmode{\systemmodeprefix\v!first}{\protect\endinput}
+
+\def\XMLrlprefix{rl:}
+
+\newwrite\XMLrllog
+
+\def\openXMLresourcelog
+ {\immediate\openout\XMLrllog\jobname.rlg\relax
+ \immediate\write\XMLrllog{\XMLbanner{standalone='yes'}}%
+ \immediate\write\XMLrllog{\writtenXMLstart{\XMLrlprefix library}}}
+
+\def\closeXMLresourcelog
+ {\immediate\write\XMLrllog{\writtenXMLend{\XMLrlprefix library}}%
+ \immediate\closeout\XMLrllog}
+
+\let\figurefilelabel \empty
+\let\figurefileoriginal \empty
+\let\figurefilefile \empty
+\let\figurefilepath \empty
+\let\figurefileconversion\empty
+\let\figurefileprefix \empty
+
+\def\XMLfeedbackresource#1#2%
+ {\begingroup
+ \defconvertedcommand\currentresourcecomment\currentresourcecomment
+ \doifnothing\figurefilefile{\edef\figurefilefile{\figurefilename.\figurefiletype}}%
+ \immediate\write\XMLrllog
+ {\writtenXMLelement{\XMLrlprefix usage}%
+ {\writtenXMLelement{\XMLrlprefix type}{#2}% 'figure' not the type in \extenalfigure
+ \writtenXMLelement{\XMLrlprefix state}{#1}% 'missing' 'found' etc
+ \ifx\figurefilelabel\empty
+ \ifx\figurelabel\s!dummy \else % otherwise label equals filename
+ \writtenXMLelementcs{\XMLrlprefix label}\figurelabel
+ \fi
+ \writtenXMLelementcs{\XMLrlprefix file}\figurefilefile % complete name
+ \writtenXMLelementcs{\XMLrlprefix name}\figurefilename % no suffix
+ \writtenXMLelementcs{\XMLrlprefix suffix}\figurefiletype
+ \else
+ % \figurefilelabel is set in x-res-04 and since
+ % we fetch from this base using the normal
+ % \externalfigure macro, the label becomes the
+ % name of the figurebase
+ \writtenXMLelementcs{\XMLrlprefix base}\figurefilename
+ \writtenXMLelementcs{\XMLrlprefix label}\figurefilelabel
+ \writtenXMLelementcs{\XMLrlprefix file}\figurefilefile
+ \fi
+ \writtenXMLelementcs{\XMLrlprefix path}\figurefilepath
+ \writtenXMLelementcs{\XMLrlprefix original}\figurefileoriginal
+ \writtenXMLelementcs{\XMLrlprefix conversion}\figurefileconversion
+ \writtenXMLelementcs{\XMLrlprefix prefix}\figurefileprefix
+ \writtenXMLelementcs{\XMLrlprefix cache}\figurefilecache
+ \ifnum\figurefilepage>\zerocount
+ \writtenXMLelement{\XMLrlprefix page}\figurefilepage
+ \fi
+ \writtenXMLelementcs{\XMLrlprefix comment}\currentresourcecomment
+ \ifconditional\externalfigureflush
+ \writtenXMLelementcs{\XMLrlprefix width}\figurewidth
+ \writtenXMLelementcs{\XMLrlprefix height}\figureheight
+ \fi}}%
+ \endgroup}
+
+\def\XMLfeedbackexternalfigure
+ {\doifmodeelse{*\v!figure}%
+ {\XMLfeedbackresource{found}}%
+ {\XMLfeedbackresource{\ifconditional\externalfigureflush missing\else registered\fi}}%
+ {figure}}
+
+\setvariables
+ [rl:manipulate]
+ [file=rlxtools.rlx]
+
+% \startsetups[rl:manipulate]
+% \doiflocfileelse{\jobname.rlx}
+% {\installprogram{texmfstart rlxtools --manipulate kpse:\jobname.rlx \jobname.rlg}}
+% {\installprogram{texmfstart rlxtools --manipulate kpse:\getvariabledefault{rl:manipulate}{file}{rlxtools.rlx} \jobname.rlg}}
+% \stopsetups
+%
+% no longer need for \setups[rl:manipulate]
+
+\ifx\nofconversionfigures\undefined \chardef\nofconversionfigures\plusone \fi
+
+\appendtoks
+ \ifcase\nofconversionfigures
+ \writestatus\m!systems{not registering rlxtools (manipulator)}%
+ \else
+ \writestatus\m!systems{registering rlxtools (manipulator)}%
+ \doiflocfileelse{\jobname.rlx}
+ {\installprogram{texmfstart rlxtools --manipulate "kpse:\jobname.rlx" "\jobname.rlg"}}
+ {\installprogram{texmfstart rlxtools --manipulate "kpse:\getvariabledefault{rl:manipulate}{file}{rlxtools.rlx}" "\jobname.rlg"}}%
+ \fi
+\to \everybye % \everylastshipout
+
+\appendtoks \openXMLresourcelog \to \everystarttext
+\appendtoks \closeXMLresourcelog \to \everystoptext
+
+\let \feedbackexternalfigure \XMLfeedbackexternalfigure
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-res-09.mkii b/tex/context/modules/mkii/x-res-09.mkii
new file mode 100644
index 000000000..e3354e9a4
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-09.mkii
@@ -0,0 +1,69 @@
+%D \module
+%D [ file=x-fig-09,
+%D version=2002.06.27,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Reporting (2),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[res-00]
+
+\defineXMLenvironment [rl:library]
+ {\starttext}
+ {\stoptext}
+
+\defineXMLenvironment [rl:usage]
+ {\bgroup}
+ {\doifnot{\XMLflush{rl:file}}{dummy}{\setups[rl:usage]}%
+ \egroup}
+
+\defineXMLsave [rl:base] % base
+\defineXMLsave [rl:type] % figure
+\defineXMLsave [rl:state] % found|missing
+\defineXMLsave [rl:label] % label
+\defineXMLsave [rl:file] % filename
+\defineXMLsave [rl:suffix] % filesuffix
+\defineXMLsave [rl:comment] % text
+\defineXMLsave [rl:width] % width in pt
+\defineXMLsave [rl:height] % height in pt
+\defineXMLsave [rl:page] % page from file
+
+\def\XMLbpentry#1%
+ {\PointsToWholeBigPoints{\XMLflush{#1}}\temp\temp bp}
+
+% \def\XMLrlentry#1#2#3%
+% {\doiftextelse{\XMLflush{#2}}
+% {\NC\bf#1\NC\XMLflush{#2}\doif{#3}{1}{ (\XMLbpentry{#2})}\NC\NR}
+% {}}
+
+\def\XMLrlentry#1#2#3%
+ {\tableiftextelse{\XMLflush{#2}}
+ {\NC\bf#1\NC\XMLflush{#2}\doif{#3}{1}{ (\XMLbpentry{#2})}\NC\NR}{}}
+
+\startsetups[rl:usage]
+
+% by using a dedicated tabulation, we permit usage in dutch interface
+
+\definetabulate[XMLRLG][|lw(4.5em)|p|]
+
+\startXMLRLG
+ \XMLrlentry {base} {rl:base} {0}
+ \XMLrlentry {type} {rl:type} {0}
+ \XMLrlentry {state} {rl:state} {0}
+ \XMLrlentry {file} {rl:file} {0}
+ \XMLrlentry {label} {rl:label} {0}
+ \XMLrlentry {suffix} {rl:suffix} {0}
+ \XMLrlentry {page} {rl:page} {0}
+ \XMLrlentry {width} {rl:width} {1}
+ \XMLrlentry {height} {rl:height} {1}
+ \XMLrlentry {comment}{rl:comment}{0}
+\stopXMLRLG
+
+\stopsetups
+
+\endinput
diff --git a/tex/context/modules/mkii/x-res-10.mkii b/tex/context/modules/mkii/x-res-10.mkii
new file mode 100644
index 000000000..833bce776
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-10.mkii
@@ -0,0 +1,75 @@
+%D \module
+%D [ file=x-fig-10,
+%D version=2003.08.02,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Dummy Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[res-00]
+
+\defineXMLenvironment [rl:library]
+ {\starttext}
+ {\stoptext}
+
+\defineXMLenvironment [rl:usage]
+ {\bgroup}
+ {\doif{\XMLflush{rl:type}-\XMLflush{rl:state}}{figure-missing}
+ {\doifnot{\XMLflush{rl:file}}{dummy}{\setups[rl:usage]}}
+ \egroup}
+
+\defineXMLsave [rl:type] % figure
+\defineXMLsave [rl:state] % found|missing
+\defineXMLsave [rl:file] % filename
+
+\defineXMLsavecontent [rl:width] {12cm} % width in pt
+\defineXMLsavecontent [rl:height] {9cm} % height in pt
+
+\useMPlibrary
+ [dum]
+
+\setupcolors
+ [state=start]
+
+\defineoverlay
+ [rl:banner]
+ [\setups{rl:banner}]
+
+\startsetups[rl:banner]
+
+ \framed [frame=off,offset=none,align={lohi,middle}]
+ \bgroup
+ \tt \white \XMLflush{rl:file}
+ \egroup
+
+\stopsetups
+
+\startsetups[rl:usage]
+
+ \startTEXpage
+
+ % \externalfigure
+ % [\XMLflush{rl:file}] % goes wrong when file present
+ % [object=no,
+ % backgroundcolor=green,background={foreground,color,rl:banner},
+ % width=\XMLflush{rl:width},
+ % height=\XMLflush{rl:height}]
+
+ \def\figurewidth {\XMLflush{rl:width}}
+ \def\figureheight{\XMLflush{rl:height}}
+
+ \externalfigurereplacement
+ {\XMLflush{rl:file}}
+ {\XMLflush{rl:file}}
+ {\XMLflush{rl:state}}
+
+ \stopTEXpage
+
+\stopsetups
+
+\endinput
diff --git a/tex/context/modules/mkii/x-res-11.mkii b/tex/context/modules/mkii/x-res-11.mkii
new file mode 100644
index 000000000..84157be88
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-11.mkii
@@ -0,0 +1,110 @@
+%D \module
+%D [ file=x-fig-11,
+%D version=2003.02.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Reporting (3),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[res-00]
+
+\defineXMLenvironment [rl:library]
+ {\starttext
+ \doiffileelse{\outputfilename.zip}{\setups[rl:attach]}{}
+ \disablemode[rl:used]}
+ {\doifnotmode{rl:used}{No images processed.}
+ \page
+ \stoptext}
+
+\defineXMLenvironment [rl:usage]
+ {\bgroup}
+ {\doifnot{\XMLflush{rl:file}}{dummy}
+ {\setups[rl:usage]
+ \enablemode[rl:used]}
+ \egroup}
+
+\defineXMLsave [rl:base] % base
+\defineXMLsave [rl:type] % figure
+\defineXMLsave [rl:state] % found|missing
+\defineXMLsave [rl:label] % label
+\defineXMLsave [rl:file] % filename
+\defineXMLsave [rl:suffix] % filesuffix
+\defineXMLsave [rl:comment] % text
+\defineXMLsave [rl:width] % width in pt
+\defineXMLsave [rl:height] % height in pt
+\defineXMLsave [rl:page] % page from file
+
+\def\XMLbpentry#1%
+ {\PointsToWholeBigPoints{\XMLflush{#1}}\temp\temp bp}
+
+\def\XMLrlentry#1#2#3%
+ {\tableiftextelse{\XMLflush{#2}}
+ {\NC\bf#1\NC\XMLflush{#2}\doif{#3}{1}{ (\XMLbpentry{#2})}\NC\NR}{}}
+
+\unprotect
+
+\setuplayout[\v!middle]
+
+\startsetups[rl:figure]
+
+ \externalfigure[\XMLflush{rl:file}][\c!width=4cm]
+
+\stopsetups
+
+\startsetups[rl:table]
+
+% by using a dedicated tabulation, we permit usage in dutch interface
+
+\definetabulate[XMLRLG][|lw(4.5em)|p|]
+
+\startXMLRLG
+ \XMLrlentry {base} {rl:base} {0}
+ \XMLrlentry {type} {rl:type} {0}
+ \XMLrlentry {state} {rl:state} {0}
+ \XMLrlentry {file} {rl:file} {0}
+ \XMLrlentry {label} {rl:label} {0}
+ \XMLrlentry {suffix} {rl:suffix} {0}
+ \XMLrlentry {page} {rl:page} {0}
+ \XMLrlentry {width} {rl:width} {1}
+ \XMLrlentry {height} {rl:height} {1}
+ \XMLrlentry {comment}{rl:comment}{0}
+\stopXMLRLG
+
+\stopsetups
+
+\startsetups[rl:usage]
+
+ \startfiguretext {\v!none} {\setups[rl:figure]}
+ \setups[rl:table]
+ \stopfiguretext
+
+\stopsetups
+
+\startsetups[rl:attach]
+
+ \useMPlibrary[nav]
+
+ \setupcolors[\c!state=\v!start]
+
+ \setupinteraction[\c!state=\v!start]
+
+ \useattachment[whatever][\outputfilename.zip]
+
+ \startlocalsetups[rl:attach:button]
+
+ \inframed
+ [\c!offset=\v!overlay,\c!frame=\v!off]
+ {\attachment[whatever]}
+
+ \stoplocalsetups
+
+ \setupfootertexts[archive with dummies: \setups{rl:attach:button}]
+
+\stopsetups
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-res-12.mkii b/tex/context/modules/mkii/x-res-12.mkii
new file mode 100644
index 000000000..81761ae9a
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-12.mkii
@@ -0,0 +1,53 @@
+%D \module
+%D [ file=x-fig-12,
+%D version=2005.05.05,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Resource Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module implements the dimension checking using \RLXTOOLS.
+
+\unprotect
+
+\chardef\figurerlxmode\plusone % rlx permitted
+
+\startXMLmapping[rli]
+ \defineXMLprocess[rl:identify]
+ \defineXMLsavecontent[rl:width] {\!!zeropoint}
+ \defineXMLsavecontent[rl:height]{\!!zeropoint}
+\stopXMLmapping
+
+\def\doanalyzefiguredimensionsrlx
+ {\ifcase\figurestatus \ifcase\figurerlxmode \else
+ \doifnotfile{\wantedfigurefullname.rli}
+ {% let's try runtime running first
+ \doshowfiguremessage6\wantedfigurefullname
+ \executesystemcommand{texmfstart rlxtools --identify \wantedfigurefullname}}%
+ \doifnotfile{\wantedfigurefullname.rli}
+ {% we assume that runtime running failed
+ \doshowfiguremessage6\wantedfigurefullname
+ \installprogram{texmfstart rlxtools --identify \wantedfigurefullname}}%
+ \doiffile{\wantedfigurefullname.rli}
+ {\global\let\analyzedfigurewidth \!!zeropoint
+ \global\let\analyzedfigureheight\!!zeropoint
+ \startnointerference % groups
+ \startXMLmapping[rli]%
+ \startXMLignore
+ \processXMLfile{\wantedfigurefullname.rli}%
+ \xdef\analyzedfigurewidth {\the\dimexpr\XMLflush{rl:width} \relax}% turn whatever into pt
+ \xdef\analyzedfigureheight{\the\dimexpr\XMLflush{rl:height}\relax}% turn whatever into pt
+ \stopXMLignore
+ \stopXMLmapping
+ \stopnointerference
+ \setanalyzedfiguredimensions\!!twelve}%
+ \fi\fi}
+
+\let\doanalyzefiguredimensionsexternal\doanalyzefiguredimensionsrlx
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-res-20.mkii b/tex/context/modules/mkii/x-res-20.mkii
new file mode 100644
index 000000000..0bc1358ec
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-20.mkii
@@ -0,0 +1,231 @@
+%D \module
+%D [ file=x-res-20,
+%D version=2006.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Lists,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D For the beginning we have used \TEXUTIL\ to hels us deal with
+%D graphics whose dimensions could not be determines and|/|or to
+%D provide placeholder info for graphics that were not available.
+%D Much of this functionality is now moved to \RLXTOOLS\ and
+%D therefore it makes sense to reimplement the code that deals with
+%D producing an overview of grapghics as well. At the same time we
+%D move some \TEX\ code from \TEXEXEC\ to here.
+%D
+%D Because the show commands are not used in real documents, but
+%D only for special purposed, it does not harm that this
+%D functionality is now part of a module. We no longer use the
+%D parsing code in \TEXUTIL, but rely on \IMAGEMAGICK's
+%D identify functionility.
+%D
+%D At the end of the file we kept the old code from \type {core-fig}.
+
+\unprotect
+
+\startXMLmapping[rlx:list]
+
+ \defineXMLprocess
+ [rl:identification]
+
+ \defineXMLenvironment
+ [rl:identify] [name=]
+ {\bgroup\ignorespaces}
+ {\removeunwantedspaces\doRLhandlegraphic\egroup}
+
+ \defineXMLsave[rl:size]
+ \defineXMLsave[rl:path]
+ \defineXMLsave[rl:width]
+ \defineXMLsave[rl:height]
+
+\stopXMLmapping
+
+\def\showexternalfigures
+ {\dosingleempty\doshowexternalfigures}
+
+\let\doRLhandlegraphic\relax
+\let\doRLstartgraphics\relax
+\let\doRLstopgraphics \relax
+
+\let\RLfigurewidth \empty
+\let\RLfigureheight\empty
+\let\RLfiguresize \empty
+\let\RLfigurefile \empty
+
+\def\doRLpresetgraphic
+ {\edef\RLfigurewidth {\the\dimexpr \XMLflush{rl:width}\relax}%
+ \edef\RLfigureheight{\the\dimexpr \XMLflush{rl:height}\relax}%
+ \edef\RLfiguresize {\the\numexpr0\XMLflush{rl:size}\relax}%
+ \edef\RLfigurefile {\XMLpar{rl:identify}{name}{unknown}}}
+
+\def\doshowexternalfigures[#1]%
+ {\bgroup
+ \dontcomplain
+ \setupcolors[\c!state=\v!start]% to prevent mps color conversion
+ \getparameters[\??ex][\c!file=rlxtools.rli,\c!alternative=a,\c!offset=\!!zeropoint,\c!size=,#1]%
+ \getvalue{\strippedcsname\doRLhandlegraphic\@@exalternative}%
+ \startXMLmapping[rlx:list]%
+ \startXMLignore
+ \doRLstartgraphics
+ \processXMLfilegrouped{\@@exfile}% \readjobfile\@@exfile\donothing\donothing
+ \doRLstopgraphics
+ \stopXMLignore
+ \stopXMLmapping
+ \egroup}
+
+\def\doRLhandlegraphica
+ {\def\doRLhandlegraphic
+ {\doRLpresetgraphic
+ \getvalue{\e!start\v!figure\e!text}[\v!left,\v!none][]
+ {}
+ {\hbox
+ {\externalfigure[\RLfigurefile][\c!frame=\v!on,\c!width=6cm,\c!size=\@@exsize]%
+ \quad
+ \framed[\c!width=\figurewidth,\c!height=\figureheight]{}%
+ \quad}}%
+ {\hbox{\tt\tfa\setstrut\strut\expanded{\asciistr{\RLfigurefile}}}}%
+ \blank
+ \tfx
+ \starttabulate[|l|l|]
+ \NC width \EQ \RLfigurewidth \NC \NR
+ \NC height \EQ \RLfigureheight \NC \NR
+ \NC size \EQ \RLfiguresize \NC \NR
+ \stoptabulate
+ \getvalue{\e!stop\v!figure\e!text}}}
+
+\def\doRLhandlegraphicb
+ {\def\doRLhandlegraphic
+ {\dontleavehmode
+ \vbox
+ {\doRLpresetgraphic
+ \hsize\dimexpr.2\hsize-.8em\relax
+ \cbox{\externalfigure[\RLfigurefile][\c!frame=\v!on,\c!factor=\v!max,\c!width=\hsize,\c!size=\@@exsize]}%
+ \vskip.5\lineheight
+ \midaligned{\tttf\RLfigurefile}}%
+ \vadjust{\vskip.2\lineheight}%
+ \quad\allowbreak}}
+
+\def\doRLhandlegraphicc
+ {\def\doRLhandlegraphic
+ {\doRLpresetgraphic
+ \pagefigure[\RLfigurefile]}}
+
+\def\doRLhandlegraphicd % this one builds a dimension file for metapost/metafun
+ {\def\doRLstartgraphics
+ {\immediate\openout\scratchwrite=mpfigs.mp\relax
+ \immediate\write\scratchwrite{\letterpercent\space graphic dimension file for metapost/metafun}}%
+ \def\doRLstopgraphics
+ {\immediate\closeout\scratchwrite}%
+ \def\doRLhandlegraphic
+ {\doRLpresetgraphic
+ \immediate\write\scratchwrite{registerfigure("\RLfigurefile",\RLfigurewidth,\RLfigureheight);}}}
+
+% \showexternalfigures[alternative=b]
+
+\protect \endinput
+
+%D Old code:
+
+\def\doshowexternalfigures[#1]%
+ {\bgroup
+ \setupcolors[\c!state=\v!start]% to prevent mps color conversion
+ \getparameters[\??ex][\c!alternative=a,\c!offset=\!!zeropoint,\c!size=,#1]%
+ \getvalue{\strippedcsname\showexternalfigure\@@exalternative}%
+ \egroup}
+
+\def\showexternalfigures
+ {\dosingleempty\doshowexternalfigures}
+
+\def\showexternalfigurea
+ {\bgroup
+ \dontcomplain
+ \def\presetfigure[##1][##2]%
+ {\getvalue{\e!start\v!figure\e!text}[\v!left,\v!none][]
+ {}
+ {\hbox
+ {\externalfigure[##1][\c!frame=\v!on,\c!width=6cm,\c!size=\@@exsize][##2]%
+ \tfskip
+ \framed[\c!width=\figurewidth,\c!height=\figureheight]{}}}%
+ {\tt\tfa\expanded{\asciistr{##1}}}%
+ \blank
+ \tfx
+ \def\docommand####1%
+ {\beforesplitstring####1\at=\to\asciia
+ \aftersplitstring ####1\at=\to\asciib
+ \defconvertedcommand\asciib\asciib
+ \doifsomething\asciib
+ {\hsmash{\hbox to .75em{\asciia\hss}: \asciib}\endgraf}}%
+ \processcommalist[##2]\docommand
+ \strut
+ \endgraf
+ \getvalue{\e!stop\v!figure\e!text}}%
+ \pushendofline
+ \readjobfile\@@exfile\donothing\donothing
+ \popendofline
+ \egroup}
+
+\def\showexternalfigureb % instelbaar maken
+ {\bgroup
+ \def\total{5}%
+ \globalletempty\allfigures
+ \doglobal\newcounter\figurecounter
+ \dontcomplain
+ \def\docommand##1{##1&}%
+ \def\figurecaptions%
+ {\crcr
+ \noalign{\nobreak\vskip.5em}%
+ \@EA\globalprocesscommalist\@EA[\allfigures]\docommand
+ \globalletempty\allfigures
+ \crcr
+ \noalign{\vskip1em\goodbreak}}%
+ \def\presetfigure[##1][##2]%
+ {\vbox
+ {\divide\hsize \total
+ \advance\hsize -1em
+ \externalfigure
+ [##1]
+ [\c!frame=\v!on,\c!factor=\v!max,\c!width=\hsize,\c!size=\@@exsize][##2]}%
+ \doglobal\addtocommalist{##1}\allfigures
+ %\getvalue{\s!figurepreset}%
+ \doglobal\increment\figurecounter
+ \ifnum\figurecounter=\total
+ \doglobal\newcounter\figurecounter
+ \def\next{\figurecaptions}%
+ \else
+ \def\next{&}%
+ \fi
+ \next}%
+ \pushendofline
+ \tabskip\zeropoint \!!plus 1fill
+ \halign to \hsize
+ {&\hss##\hss\cr\readjobfile\@@exfile\donothing\donothing\crcr
+ \figurecaptions}
+ \popendofline
+ \egroup}
+
+\def\showexternalfigurec
+ {\bgroup
+ \def\presetfigure[##1][##2]{\expanded{\pagefigure[##1][\c!size=\@@exsize]}}% else loop
+ \pushendofline
+ \readjobfile\@@exfile\donothing\donothing
+ \popendofline
+ \egroup}
+
+\def\showexternalfigured % to be documented; this one builds a dimension file for
+ {\bgroup % metapost/metafun
+ \immediate\openout\scratchwrite=mpfigs.mp
+ \def\presetfigure[##1][##2]%
+ {\getfiguredimensionsonly[##1]% \pagefigure[##1]%
+ \immediate\write\scratchwrite
+ {registerfigure("##1",\figurewidth,\figureheight);}}
+ \pushendofline
+ \readjobfile\@@exfile\donothing\donothing
+ \popendofline
+ \immediate\closeout\scratchwrite
+ \egroup}
diff --git a/tex/context/modules/mkii/x-res-50.mkii b/tex/context/modules/mkii/x-res-50.mkii
new file mode 100644
index 000000000..3c3e758a7
--- /dev/null
+++ b/tex/context/modules/mkii/x-res-50.mkii
@@ -0,0 +1,427 @@
+%D \module
+%D [ file=x-res-50,
+%D version=2004.02.18,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Multimedia Presentation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is a preliminary module, using a preliminary xml media format that
+%D looks as follows (record is embedded in resource library element):
+%D
+%D \starttyping
+%D <rl:mediaclip label="sample 1">
+%D <rl:name>Sample One</rl:name>
+%D <rl:mime>application/x-shockwave-flash</rl:mime>
+%D <rl:file>http://localhost/mb.swf</rl:file>
+%D <rl:width>8cm</rl:width>
+%D <rl:height>6cm</rl:height>
+%D <rl:text>Nothing special to be said.</rl:text>
+%D <rl:picture>cow.pdf</rl:picture>
+%D </rl:mediaclip>
+%D
+%D <rl:mediaclip label="sample 2">
+%D <rl:name>Sample Two</rl:name>
+%D <rl:mime>audio/mpeg</rl:mime>
+%D <rl:file>mb.mp3</rl:file>
+%D <rl:picture>mb.jpg</rl:picture>
+%D </rl:mediaclip>
+%D \stoptyping
+%D
+%D \starttyping
+%D texexec --pdf --use=med-show yourfile.xml
+%D \stoptyping
+%D
+%D Bonus:
+%D
+%D \starttyping
+%D --arg="url=http://localhost:8881/e:/media"
+%D \stoptyping
+
+% output=pdftex
+
+% \nopdfcompression
+
+% bugs in recognizing embedded stream cq. player
+% bugs in layers + hide/vide
+% bugs in save javascripts
+% bugs all over the place
+
+% in principe kan menu overal hetzelfde zijn als we via JS per pagina de clip var zetten,
+% hoewel, misschien zal het menu gaan afhangen van de soort clip
+
+% property (eigenschap) aan framed en layer
+
+\usemodule[meta-dum] \usemodule[contml] \autoXMLnamespace [context]
+
+\doifelsevariable{environment}{url}
+ {\setvariables[mediaclip][url=\getvariable{environment}{url}/]}
+ {\setvariables[mediaclip][url=]}
+
+\startmode [silent]
+
+ \setvariables[mediaclip:option][start=]
+
+\stopmode
+
+\startnotmode [silent]
+
+ \setvariables[mediaclip:option][start=auto]
+
+\stopnotmode
+
+\chardef\XMLtokensreduction=1 \dontcomplain % \showframe \pdfcompresslevel=0
+
+\setuppapersize
+ [S6][S6]
+
+\definemeasure [GapSize] [\dimexpr( 15pt)]
+\definemeasure [EdgeWidth] [\dimexpr(100pt)]
+\definemeasure [TextWidth] [\dimexpr(.5\textwidth)]
+\definemeasure [RenderingWidth] [\dimexpr(\textwidth)]
+\definemeasure [RenderingHeight] [\dimexpr(\textheight)]
+
+% \XMLflush{rl:ratio}\dimexpr(.75\textwidth),
+
+\setuplayout
+ [backspace=\measure{GapSize},
+ topspace=\measure{GapSize},
+ header=0pt,
+ footer=0pt,
+ margin=0pt,
+ edgedistance=2\measure{GapSize},
+ rightedge=\measure{EdgeWidth},
+ bottomdistance=2\measure{GapSize},
+ bottom=2\measure{GapSize},
+ height=fit,
+ width=fit]
+
+\setupinteraction
+ [state=start,
+ color=lightgray,
+ contrastcolor=lightgray,
+ openaction=PresetFields,
+ closeaction=ForgetChanges,
+ menu=on,
+ click=no]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupcolors
+ [state=start]
+
+\usetypescript
+ [palatino][texnansi]
+
+\setupbodyfont
+ [palatino]
+
+\definecolor[darkgray] [s=.2]
+\definecolor[mediumgray][s=.5]
+\definecolor[lightgray] [s=.8]
+\definecolor[transgray] [s=1,t=.9,a=1]
+
+\setupbackgrounds
+ [page]
+ [backgroundoffset=\measure{GapSize},
+ background={color,pagebutton},
+ backgroundcolor=black]
+
+\definelayer
+ [main]
+ [width=\textwidth,
+ height=\textheight]
+
+\definelayer
+ [extra]
+ [width=\rightedgewidth,
+ height=\bottomheight]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=0pt,
+ background=main]
+
+\setupbackgrounds
+ [bottom][rightedge]
+ [backgroundoffset=0pt,
+ background=extra]
+
+% java scripts
+
+\startJSpreamble {handy} used now
+
+ function ForgetChanges ()
+ { this.dirty = false }
+
+ function PresetFields ()
+ { this.syncAnnotScan() }
+
+\stopJSpreamble
+
+\definereference[PresetFields] [JS(PresetFields)]
+\definereference[ForgetChanges][JS(ForgetChanges)]
+
+% layers
+
+\defineproperty [menulayer] [layer] [title=menulayer]
+\defineproperty [textlayer] [layer] [title=textlayer,state=stop]
+\defineproperty [datalayer] [layer] [title=datalayer,state=stop]
+
+\setupfield
+ [rollbutton]
+ [fieldlayer=menulayer]
+
+\setupfield
+ [rollbutton]
+ [option=auto]
+
+\definepalet
+ [rollover]
+ [n=darkgray,
+ r=lightgray,
+ d=darkgray]
+
+% list
+
+\definelist
+ [clips]
+ [expansion=yes,
+ criterium=text,
+ alternative=f]
+
+% navigation
+
+\defineoverlay[pagebutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer},ToggleLayer{menulayer}}]
+\defineoverlay[textbutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}]
+\defineoverlay[databutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}]
+
+% clips
+
+\defineXMLenvironment
+ [rl:mediaclip]
+ {\setups[mediaclip:start]}
+ {\setups[mediaclip:stop]}
+
+\newcounter\MediaClip
+
+\startsetups[mediaclip:start]
+
+ \bgroup \startXMLignore
+
+ % no \startstandardmakeup here since we need the dsta in the menuconstruction
+
+ \defineXMLsave [rl:name]
+ \defineXMLsave [rl:visualization]
+ \defineXMLsave [rl:file]
+ \defineXMLsave [rl:mime]
+ \defineXMLsave [rl:picture] [backgroundcolor=lightgray]
+
+ \defineXMLsavecontent [rl:text] {No additional info.}
+ \defineXMLsavecontent [rl:width] {\measure{RenderingWidth}}
+ \defineXMLsavecontent [rl:height] {\measure{RenderingHeight}}
+ \defineXMLsavecontent [rl:aspect] {1}
+
+\stopsetups
+
+\startsetups[mediaclip:stop]
+
+ \startstandardmakeup
+
+ \doifXMLdataelse{rl:file}
+ {\setups[mediaclip:file:yes]}
+ {}
+
+ \doifXMLdataelse{rl:picture}
+ {\doifelse{\XMLflush{rl:picture}}{self}
+ {\setups[mediaclip:picture:self]}
+ {\setups[mediaclip:picture:yes]}}
+ {\setups[mediaclip:picture:no]}
+
+ \doifXMLdata{rl:text}
+ {\setups[mediaclip:text]}
+
+ \setlayerframed
+ [extra]
+ [preset=rightbottom]
+ [frame=off,offset=overlay,width=fit,background=databutton,align=left]
+ {\startproperty[datalayer]\setups[mediaclip:data]\stopproperty}
+
+ \doifXMLdataelse{rl:name}
+ {\writetolist[clips]{}{\XMLflush{rl:name}}}
+ {\writetolist[clips]{}{\XMLpar{rl:mediaclip}{label}{unknown}}}
+
+ \stopstandardmakeup
+
+ \stopXMLignore \egroup
+
+\stopsetups
+
+\setuptabulate
+ [before=,
+ after=]
+
+\def\rlCleanupFileName#1%
+ {\bgroup
+ \def\cleanup##1##2{\ifnum##1##2=20 \space\else\char\octnumber{##1##2}\fi}%
+ \defineactivecharacter 37 {\cleanup}%
+ \scantokens{#1}%
+ \egroup}
+
+\startsetups[mediaclip:data]
+
+ \noindent \buttonframed
+ [framecolor=lightgray,
+ foregroundcolor=lightgray]
+ {\bf\expanded{\rlCleanupFileName{\XMLflush{rl:file}}}}
+
+ \vskip.75\measure{GapSize}
+
+ \noindent \buttonframed
+ [framecolor=lightgray,
+ foregroundcolor=lightgray]
+ {\bf\XMLflush{rl:mime}}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:self]
+
+ \definerenderingwindow
+ [mediaclip]
+ [width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height},
+ frame=off,
+ openpageaction=StartCurrentRendering,
+ closepageaction=StopCurrentRendering]
+
+ \setlayer
+ [main]
+ {\placerenderingwindow[mediaclip][mediaclip-\MediaClip]}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:yes]
+
+ \setlayer
+ [main]
+ {\externalfigure
+ [\XMLflush{rl:picture}]
+ [background=color,
+ backgroundcolor=\XMLpar{rl:picture}{backgroundcolor}{lightgray},
+ factor=max,
+ width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height}]}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:no]
+
+ \setlayer
+ [main]
+ {\externalfigure
+ [dummy]
+ [width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height}]}
+
+\stopsetups
+
+\startsetups[mediaclip:file:yes]
+
+ \doglobal\increment\MediaClip
+
+ \useexternalrendering
+ [mediaclip-\MediaClip]
+ [\XMLflush{rl:mime}]
+ [\getvariable{mediaclip}{url}\XMLflush{rl:file}]
+ [\getvariable{mediaclip:option}{start}]
+
+\stopsetups
+
+\defineinteractionmenu
+ [navigation] [right]
+
+\defineinteractionmenu
+ [control] [bottom]
+
+\setupinteractionmenu
+ [navigation,control]
+ [state=start,
+ frame=on,
+ middle=\hskip.5\measure{GapSize},
+ inbetween=\vskip.5\measure{GapSize}]
+
+\setupinteractionmenu
+ [right,bottom]
+ [distance=overlay]
+
+\startinteractionmenu [navigation]
+ \rob [HideLayer{textlayer},FirstPage] First Page \\
+ \rob [HideLayer{textlayer},PreviousPage] Previous Page \\
+ \rob [HideLayer{textlayer},NextPage] Next Page \\
+ \rob [HideLayer{textlayer},LastPage] Last Page \\
+ \rob [HideLayer{textlayer},clips] List Of Clips \\
+ \rob [ForgetChanges,CloseDocument] Close Document \\
+\stopinteractionmenu
+
+\startinteractionmenu [control]
+ \rob [StartRendering{mediaclip-\MediaClip}] Start \\
+ \rob [StopRendering{mediaclip-\MediaClip}] Stop \\
+ \rob [PauseRendering{mediaclip-\MediaClip}] Pause \\
+ \rob [ResumeRendering{mediaclip-\MediaClip}] Resume \\
+ \rob [ToggleLayer{datalayer}] Info \\
+ \doifXMLdata{rl:text}{\rob [HideLayer{datalayer},ToggleLayer{textlayer}] Text \\}
+\stopinteractionmenu
+
+\startsetups[mediaclip:text]
+
+ \setlayer
+ [extra]
+ [preset=rightbottom]
+ {\startproperty[textlayer]
+ \framed
+ [align=normal,
+ frame=off,
+ width=\measure{TextWidth},
+ foregroundcolor=darkgray,
+ background={color,textbutton},
+ backgroundcolor=lightgray]
+ {\XMLflush{rl:text}}
+ \stopproperty}
+
+\stopsetups
+
+\setupcolors[textcolor=lightgray]
+
+\startsetups [library:start]
+
+ \starttext
+
+ \setupinteractionmenu[control][state=stop]
+
+ \title[clips]{List of Media Clips}
+
+ \placelist[clips] \page
+
+ \setupinteractionmenu[control][state=start]
+
+\stopsetups
+
+\startsetups [library:stop]
+
+ \stoptext
+
+\stopsetups
+
+\defineXMLenvironment [rl:resourcelibrary]
+ {\setups[library:start]}
+ {\setups[library:stop]}
+
+\doifelsenothing{\inputfilename}
+ {\processXMLfile{mediaclient.xml}}
+ {\processXMLfile{\inputfilename}}
diff --git a/tex/context/modules/mkii/x-sch-00.mkii b/tex/context/modules/mkii/x-sch-00.mkii
new file mode 100644
index 000000000..5b4da0825
--- /dev/null
+++ b/tex/context/modules/mkii/x-sch-00.mkii
@@ -0,0 +1,382 @@
+%D \module
+%D [ file=x-sch-00,
+%D version=2001.10.02,
+%D title=\CONTEXT\ Style File,
+%D subtitle=XML Schema Basics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Schema support was implemented right after euro\TeX\ 2001,
+%D when Tobias Burnus send me a schema for the XML figure
+%D base. Since it happened that I needed schemata for other
+%D projects too, I wrote this mapper. Thanks to Tobias for
+%D testing it.
+
+\newcounter\XSDprefix
+\newif\ifXDScomposite
+
+\definelist [xsd:names]
+\defineregister [xsd:index] [xsd:indices]
+
+\setuplist [xsd:names] [expansion=yes]
+\setupregister [xsd:index] [expansion=yes]
+
+\def\dodoXSDkeyval#1#2#3%
+ {\framed
+ [width=\hsize,background=color,backgroundcolor=xsd:0,
+ framecolor=xsd:0,frame=off,align=right]
+ {\hbox to 5em % %to 8em % .2\hsize
+ {\bf
+ %\doifsomething{#1}{#1 }
+ \ignorespaces#2\unskip\hss}
+ %\ignorespaces#2\unskip:}%
+ \space
+ \ignorespaces#3\unskip}}
+
+\def\doXSDkeyval#1#2#3#4%
+ {\bgroup
+ \edef\XSDtemp{\XMLpar{#3}{#4}{}}%
+ \doifsomething{\XSDtemp}
+ {\def\doXSDtemp{\dodoXSDkeyval{#1}{#2}{\XSDtemp}}%
+ \def\doXSDtype{\dodoXSDkeyval{#1}{#2}{\XMLtyp{#3}{#4}{}}}%
+ \setupinteraction[color=,contrastcolor=,style=]%
+ \processaction
+ [#4]
+ [ value=>\doXSDtype,
+ name=>{\writetolist[xsd:names]{}{\XSDtemp}%
+ \writetoregister[xsd:index]{\XSDtemp}%
+ \ifXDScomposite \else
+ \pagereference[xsd:\XSDprefix:\XSDtemp]%
+ \fi
+ \doXSDtemp},
+ type=>{\doifinstringelse{xsd:}{\XSDtemp}
+ {\doXSDtemp}
+ {\gotobox{\doXSDtemp}[xsd:\XSDprefix:\XSDtemp]}},
+ ref=>{\doifinstringelse{xsd:}{\XSDtemp}
+ {\doXSDtemp}
+ {\gotobox{\doXSDtemp}[xsd:\XSDprefix:\XSDtemp]}},
+ unknown=>\doXSDtemp]}%
+ \endgraf
+ \egroup}
+
+\def\doXSDkeyvals#1#2#3%
+ {\def\docommand##1{\doXSDkeyval{#1}{##1}{#2}{##1}}%
+ \processcommalist[#3]\docommand}
+
+\def\dodoXSDbanner#1%
+ {\framed
+ [width=\hsize,framecolor=xsd:0,frame=off,
+ background=color,backgroundcolor=xsd:0]
+ {\ignorespaces#1\unskip}}
+
+\def\doXSDtitle#1#2#3%
+ {\edef\XSDtemp{\XMLpar{#2}{#3}{}}%
+ \dodoXSDbanner
+ {{\bf\ignorespaces#1\unskip}%
+ \doifsomething{\XSDtemp}
+ {:\space\ignorespaces\XSDtemp\unskip
+ \pagereference[xsd:\XSDprefix:\XSDtemp]}}}
+
+\def\doXSDbanner#1%
+ {\dodoXSDbanner{\bf#1}}
+
+%D We use colored backgrounds for meaningful blocks.
+
+\definecolor [xsd:0] [white]
+
+\definecolor [xsd:1] [s=.30]
+\definecolor [xsd:2] [s=.55]
+\definecolor [xsd:3] [s=.70]
+\definecolor [xsd:4] [s=.85]
+
+\definecolor [xsd:5] [r=.6,g=.7,b=.8]
+\definecolor [xsd:6] [r=.7,g=.8,b=.6]
+\definecolor [xsd:7] [r=1,g=1,b=.6]
+\definecolor [xsd:8] [r=.8,g=.7,b=.6]
+
+\defineframedtext [XSDannotation] [backgroundcolor=xsd:0]
+
+\defineframedtext [XSDelement] [backgroundcolor=xsd:5]
+\defineframedtext [XSDattribute] [backgroundcolor=xsd:6]
+\defineframedtext [XSDsimpleType] [backgroundcolor=xsd:7]
+\defineframedtext [XSDcomplexType] [backgroundcolor=xsd:8]
+
+\defineframedtext [XSDcomplexContent] [backgroundcolor=xsd:1]
+\defineframedtext [XSDsimpleContent] [backgroundcolor=xsd:1]
+\defineframedtext [XSDattributeGroup] [backgroundcolor=xsd:1]
+
+\defineframedtext [XSDcapsule] [backgroundcolor=xsd:2]
+\defineframedtext [XSDsequence] [backgroundcolor=xsd:3]
+
+\def\XDSstructures% handy for external settings
+ {XSDannotation,
+ XSDcomplexType,XSDsimpleType,XSDelement,XSDattribute,
+ XSDcomplexContent,XSDsimpleContent,XSDattributeGroup,
+ XSDcapsule,XSDsequence}
+
+\setupframedtexts
+ [\XDSstructures]
+ [width=\hsize,
+ offset=.5\bodyfontsize,
+ location=none,
+ background=color,
+ framecolor=xsd:0,
+ before=\ifinframed\else\blank\fi,
+ after=\ifinframed\else\blank\fi,
+ depthcorrection=off,
+ rulethickness=1pt,
+ strut=no]
+
+\definesymbol[xsd][{\blackrule[width=4em]}]
+
+\def\placeXSDlegenda
+ {\startbaselinecorrection
+ \starttabulate[|l|l|]
+ \HL
+ \NC \bf color \NC \bf meaning \NC \NR
+ \HL
+ \NC \color[xsd:1]{\symbol[xsd]} \NC complexContent \unskip\quad
+ simpleContent \unskip\quad
+ attributeGroup \NC \NR
+ \NC \color[xsd:2]{\symbol[xsd]} \NC capsule \NC \NR
+ \NC \color[xsd:3]{\symbol[xsd]} \NC sequence \NC \NR
+ \HL
+ \NC \color[xsd:5]{\symbol[xsd]} \NC element \NC \NR
+ \NC \color[xsd:6]{\symbol[xsd]} \NC attribute \NC \NR
+ \NC \color[xsd:7]{\symbol[xsd]} \NC simpleType \NC \NR
+ \NC \color[xsd:8]{\symbol[xsd]} \NC complexType \NC \NR
+ \HL
+ \stoptabulate
+ \stopbaselinecorrection}
+
+\defineXMLenvironment [xsd:all] [id=]
+ {\startXSDcapsule
+ \doXSDbanner{all}
+ \doXSDkeyvals{all}{xsd:all}{id}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:annotation]
+ {\startXSDcapsule
+ \doXSDbanner{annotation}
+ \startXSDannotation}
+ {\stopXSDannotation
+ \stopXSDcapsule}
+
+\defineXMLignore [xsd:appInfo]
+
+\defineXMLenvironment [xsd:attribute]
+ [id=,name=,ref=,type=,form=,use=,value=]
+ {\startXSDattribute
+ \doifelsenothing{\XMLpar{xsd:attribute}{ref}{}}
+ {\doXSDkeyvals{attribute}{xsd:attribute}{name,type}}
+ {\doXSDkeyvals{attribute}{xsd:attribute}{ref}}
+ \doXSDkeyvals{attribute}{xsd:attribute}{id,form,use,value}
+ \XDScompositetrue}
+ {\stopXSDattribute}
+
+\defineXMLenvironment [xsd:attributeGroup] [id=,name=,ref=]
+ {\startXSDattributeGroup
+ \doXSDtitle{attribute group}{xsd:attributeGroup}{name}
+ \doXSDkeyvals{attr group}{xsd:attributeGroup}{id,name,ref}
+ \XDScompositetrue}
+ {\stopXSDattributeGroup}
+
+\defineXMLenvironment [xsd:choice] [id=,minOccurs=,maxOccurs=]
+ {\startXSDcapsule
+ \doXSDbanner{choice}
+ \doXSDkeyvals{choice}{xsd:choice}{id,minOccurs,maxOccurs}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:complexContent] [id=,mixed=]
+ {\startXSDcomplexContent
+ \doXSDkeyvals{complex content}{xsd:complexContent}{id,mixed}
+ \XDScompositetrue}
+ {\stopXSDcomplexContent}
+
+\defineXMLenvironment [xsd:complexType]
+ [id=,abstract=,block=,final=,mixed=,name=]
+ {\startXSDcomplexType
+ \doXSDtitle{complex type}{xsd:complexType}{name}
+ \doXSDkeyvals{complex type}{xsd:complexType}{id,abstract,block,final,mixed}
+ \XDScompositetrue}
+ {\stopXSDcomplexType}
+
+\defineXMLenvironment [xsd:documentation] [source=,xml:lang=]
+ {\endgraf\bgroup\setupwhitespace[big]}
+ {\endgraf\egroup}
+
+\defineXMLenvironment [xsd:element]
+ [name=,type=,ref=,
+ abstract=,block=,default=,final=,fixed=,form=,id=,
+ minOccurs=,maxOccurs=,nullable=,substitutionGroup=]
+ {\startXSDelement
+ \doifelsenothing{\XMLpar{xsd:element}{ref}{}}
+ {\doXSDkeyvals{element}{xsd:element}{name,type}}
+ {\doXSDkeyvals{element}{xsd:element}{ref}}
+ \doXSDkeyvals{element}{xsd:element}
+ {id,abstract,block,default,final,fixed,form,
+ minOccurs,maxOccurs,nullable,substitutionGroup}
+ \XDScompositetrue}
+ {\stopXSDelement}
+
+\defineXMLenvironment [xsd:extension] [id=,base=]
+ {\startXSDcapsule
+ \doXSDbanner{extension}
+ \doXSDkeyvals{extension}{xsd:extension}{id,base}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:group]
+ [id=,name=,ref=,minOccurs=,maxOccurs=]
+ {\startXSDcapsule
+ \doXSDbanner{group}
+ \doXSDkeyvals{group}{xsd:group}{id,name,ref,minOccurs,maxOccurs}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:key] [id=,name=]
+ {\startXSDcapsule
+ \doXSDbanner{key}
+ \doXSDkeyvals{key}{xsd:key}{id,name}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:keyref] [id=,name=,refer=]
+ {\startXSDcapsule
+ \doXSDbanner{keyref}
+ \doXSDkeyvals{key ref}{xsd:keyref}{id,name,refer}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:list] [id=,itemType=]
+ {\startXSDcapsule
+ \doXSDbanner{list}
+ \doXSDkeyvals{list}{xsd:list}{id,itemType}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:redefine] [schemaLocation=]
+ {\startXSDcapsule
+ \doXSDbanner{redefine}
+ \doXSDkeyvals{redefine}{xsd:redefine}{schemaLocation}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:restriction] [id=,base=]
+ {\startXSDcapsule
+ \doXSDbanner{restriction}
+ \doXSDkeyvals{restriction}{xsd:restriction}{id,base}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:schema]
+ [attributeFormDefault=,blockDefault=,elementFormDefault=,
+ finalDefault=,id=,targetNamespace=,version=]
+ {\startXSDcapsule
+ \doglobal\increment\XSDprefix
+ \doXSDbanner{schema}
+ \doXSDkeyvals{schema}{xsd:schema}
+ {attributeFormDefault,blockDefault,elementFormDefault,
+ finalDefault,id,targetNamespace,version}
+ \stopXSDcapsule}
+ {}
+
+\defineXMLenvironment [xsd:sequence] [id=,minOccurs=,maxOccurs=]
+ {\startXSDsequence
+ \doXSDbanner{sequence}
+ \doXSDkeyvals{sequence}{xsd:sequence}{id,minOccurs,maxOccurs}
+ \XDScompositetrue}
+ {\stopXSDsequence}
+
+\defineXMLenvironment [xsd:simpleContent] [id=]
+ {\startXSDsimpleContent
+ \doXSDkeyvals{simple content}{xsd:simpleContent}{id}
+ \XDScompositetrue}
+ {\stopXSDsimpleContent}
+
+\defineXMLenvironment [xsd:simpleType] [id=,name=]
+ {\startXSDsimpleType
+ \doXSDtitle{simple type}{xsd:simpleType}{name}
+ \doXSDkeyvals{simple type}{xsd:simpleType}{id}
+ \XDScompositetrue}
+ {\stopXSDsimpleType}
+
+\defineXMLenvironment [xsd:union] [id=,memberTypes=]
+ {\startXSDcapsule
+ \doXSDbanner{union}
+ \doXSDkeyvals{union}{xsd:union}{id,memberTypes}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\defineXMLenvironment [xsd:unique] [id=,name=]
+ {\startXSDcapsule
+ \doXSDbanner{unique}
+ \doXSDkeyvals{unique}{xsd:unique}{id,name}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+
+\def\defineXSDfacet
+ {\dotripleempty\dodefineXSDfacet}
+
+\def\dodefineXSDfacet[#1][#2][#3]%
+ {\defineXMLenvironment[xsd:#1][#2]
+ {\startXSDcapsule
+ \doXSDkeyvals{#1}{xsd:#1}{#3}
+ \XDScompositetrue}
+ {\stopXSDcapsule}
+ \defineXMLsingular[xsd:#1][#2]
+ {\doXSDkeyvals{#1}{xsd:#1}{#3}}}
+
+\defineXSDfacet [duration] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [encoding] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [enumeration] [id=,value=,fixed=] [id,value,fixed]
+
+\defineXSDfacet [length] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [minLength] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [maxLength] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [minInclusive] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [maxInclusive] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [minExclusive] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [maxExclusive] [id=,value=,fixed=] [id,value,fixed]
+
+\defineXSDfacet [pattern] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [period] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [precision] [id=,value=,fixed=] [id,value,fixed]
+\defineXSDfacet [scale] [id=,value=,fixed=] [id,value,fixed]
+
+\defineXSDfacet [field] [id=,xpath=] [id,xpath]
+\defineXSDfacet [selector] [id=,xpath=] [id,xpath]
+
+\defineXSDfacet
+ [any]
+ [id=,namespace=,minOccurs=,maxOccurs=,processContents=]
+ [id,namespace,minOccurs,maxOccurs,processContent]
+
+\defineXSDfacet
+ [anyAttribute]
+ [id=,namespace=,processContents=]
+ [id,namespace,processContents]
+
+\defineXSDfacet
+ [import]
+ [id=,namespace=,schemaLocation=]
+ [id,namespace,schemaLocation]
+
+\defineXSDfacet
+ [include]
+ [id=,schemaLocation=]
+ [id,schemaLocation]
+
+\defineXSDfacet
+ [notation]
+ [id=,name=,public=,system=]
+ [id,name,public,system]
+
+\endinput
diff --git a/tex/context/modules/mkii/x-sch-01.mkii b/tex/context/modules/mkii/x-sch-01.mkii
new file mode 100644
index 000000000..5bdf088fe
--- /dev/null
+++ b/tex/context/modules/mkii/x-sch-01.mkii
@@ -0,0 +1,122 @@
+%D \module
+%D [ file=x-sch-01,
+%D version=2001.10.04,
+%D title=\CONTEXT\ Style File,
+%D subtitle=XML Schema Presentation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This style wraps around the core schema visualizer,
+%D implemented in \type {x-sch-00}. This is an experimental
+%D style, more will follow.
+%D
+%D \starttyping
+%D texexec --use=sch-01 x-fig-00.xsd --pdf
+%D \stoptyping
+
+\doifnothing {\jobfilename} {\end}
+\doiffileelse {\jobfilename.xsd} {} {\end}
+
+\usemodule[sch-00,con-01]
+
+\remapXMLnamespace [xs] [xsd]
+
+\setuplayout
+ [backspace=1.5cm,
+ topspace=1.5cm,
+ bottomspace=1cm,
+ width=middle,
+ height=middle,
+ header=1.5cm,
+ footer=1.5cm]
+
+\setupcolors
+ [state=start]
+
+\setupbackgrounds
+ [page]
+ [background=goback]
+
+\setupbackgrounds
+ [text]
+ [background=gonext]
+
+\defineoverlay
+ [goback]
+ [\overlaybutton{PreviousJump}]
+
+\defineoverlay
+ [gonext]
+ [\overlaybutton{nextpage}]
+
+\setuppagenumbering
+ [location=footer]
+
+\usetypescript
+ [palatino]
+ [\defaultencoding]
+
+\setupbodyfont
+ [palatino,10pt]
+
+%\setupinteraction
+% [state=start,
+% color=,
+% contrastcolor=,
+% style=]
+
+\setuplist
+ [xsd:names]
+ [interaction=all,
+ width=0pt,
+ alternative=c]
+
+\setupregister
+ [xsd:index]
+ [interaction=text,
+ symbol=none]
+
+\setuphead
+ [chapter]
+ [style=\bfd,
+ header=high]
+
+\setuphead
+ [section]
+ [style=\bfb]
+
+\lowercasestring \jobfilename \to \lcjobfilename
+
+\setupheadertexts
+ [\lcjobfilename]
+
+\starttext
+
+\title{Schema \quote{\lcjobfilename.xsd}}
+
+\subject{Names in order of definition}
+
+\startcolumns[n=3]
+ \placelist[xsd:names][criterium=current]
+\stopcolumns
+
+\subject{Names in alphabetic order}
+
+\startcolumns[n=3]
+ \placeregister[xsd:index][criterium=current]
+\stopcolumns
+
+\subject{Meaning of background colors}
+
+\placeXSDlegenda
+
+\subject{Schema components}
+
+\processXMLfilegrouped{\jobfilename.xsd}
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-set-01.mkii b/tex/context/modules/mkii/x-set-01.mkii
new file mode 100644
index 000000000..814ea5fc6
--- /dev/null
+++ b/tex/context/modules/mkii/x-set-01.mkii
@@ -0,0 +1,79 @@
+%D \module
+%D [ file=x-set-01,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Mappings,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This file is obsolete.
+
+\endinput
+
+\unprotect
+
+\def\SETUPnamespace{xmlns:cd="http://www.pragma-ade.com/commands"}
+
+\bgroup \catcode`\<=\@@other
+
+\unexpanded\gdef\dostring#1#2#3%
+ {\immediate\write\scratchwrite{#1<#2cd:#3>}}
+
+\gdef\doline#1%
+ {\immediate\write\scratchwrite{#1}}
+
+\egroup
+
+\def\startsetupfile
+ {\immediate\openout\scratchwrite=keys-\currentlanguage.xml
+ \doline{\string<?xml version="1.0"?>}
+ \doline{}
+ \dostring{}{}{interface \SETUPnamespace\space name="context" language="\currentlanguage" version="\contextversion"}}
+
+\def\stopsetupfile
+ {\doline{}
+ \dostring{}{/}{interface}
+ \immediate\closeout\scratchwrite}
+
+\def\interfacecomponenttoxml#1#2#3%
+ {\doifelse{#3}\nointerfaceobject
+ {\dostring{\space\space\space\space}{}{#1 name="#2" value="#2"/}}
+ {\dostring{\space\space\space\space}{}{#1 name="#2" value="#3"/}}}
+
+\def\setinterfaceconstant{\interfacecomponenttoxml{constant}}
+\def\setinterfacevariable{\interfacecomponenttoxml{variable}}
+\def\setinterfaceelement {\interfacecomponenttoxml{element}}
+\def\setinterfacecommand {\interfacecomponenttoxml{command}}
+
+\def\startinterfacexmlcomponent{\doline{}\dostring{\space\space}{}} % #1
+\def\stopinterfacexmlcomponent {\dostring{\space\space}{/}} % #1
+
+\let\normalstartvariables\startvariables \let\normalstopvariables\stopvariables
+\let\normalstartconstants\startconstants \let\normalstopconstants\stopconstants
+\let\normalstartcommands \startcommands \let\normalstopcommands \stopcommands
+\let\normalstartelements \startelements \let\normalstopelements \stopelements
+
+\def\startvariables{\startinterfacexmlcomponent{variables}\normalstartvariables}
+\def\startconstants{\startinterfacexmlcomponent{constants}\normalstartconstants}
+\def\startcommands {\startinterfacexmlcomponent{commands} \normalstartcommands }
+\def\startelements {\startinterfacexmlcomponent{elements} \normalstartelements }
+
+\def\stopvariables{\stopinterfacexmlcomponent{variables}\normalstopvariables}
+\def\stopconstants{\stopinterfacexmlcomponent{constants}\normalstopconstants}
+\def\stopcommands {\stopinterfacexmlcomponent{commands} \normalstopcommands }
+\def\stopelements {\stopinterfacexmlcomponent{elements} \normalstopelements }
+
+\protect
+
+\starttext
+ \startsetupfile
+ \input mult-con.tex
+ \input mult-com.tex
+ \stopsetupfile
+\stoptext
diff --git a/tex/context/modules/mkii/x-set-02.mkii b/tex/context/modules/mkii/x-set-02.mkii
new file mode 100644
index 000000000..7a2cd7701
--- /dev/null
+++ b/tex/context/modules/mkii/x-set-02.mkii
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=x-set-02,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Mappings,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect \bgroup \catcode`\<=\@@other
+
+\def\setinterfacecomponent#1#2#3%
+ {\setgvalue{\string<#1\string:#2\string>}{#3}}
+
+\gdef\getinterfacecomponent#1#2%
+ {\executeifdefined{\string<#1\string:#2\string>}{#2}}
+
+\def\setinterfaceconstant{\setinterfacecomponent{constant}} % constant
+\def\setinterfacevariable{\setinterfacecomponent{variable}} % variable
+\def\setinterfaceelement {\setinterfacecomponent{string}} % element
+\def\setinterfacecommand {\setinterfacecomponent{string}} % command
+
+\input mult-\userinterfacetag.mkii
+
+\egroup \protect \endinput
diff --git a/tex/context/modules/mkii/x-set-11.mkii b/tex/context/modules/mkii/x-set-11.mkii
new file mode 100644
index 000000000..8c8f614a5
--- /dev/null
+++ b/tex/context/modules/mkii/x-set-11.mkii
@@ -0,0 +1,837 @@
+%D \module
+%D [ file=x-set-11,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Definitions,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% module x-set-02 loads the mapping, after that we can say:
+%
+% texmfstart texexec --int=nl --pdf --global --result=setup-nl x-set-12
+
+\startmessages dutch library: setup
+ title: setup
+ formula: formule
+ number: getal
+ list: lijst
+ dimension: maat
+ mark: markering
+ reference: verwijzing
+ command: commando
+ file: file
+ name: naam
+ identifier: naam
+ text: tekst
+ section: sectie
+ singular: naam enkelvoud
+ plural: naam meervoud
+ matrix: n*m
+ see: zie
+ inherits: erft van
+ 1: de karakters < en > zijn globaal actief!
+ 2: -- wordt verwerkt
+ 3: -- is niet gedefinieerd
+ 4: -- wordt nogmaals verwerkt
+ optional: optioneel
+ displaymath: formule
+ index: ingang
+ math: formule
+ nothing: leeg
+ file: file
+ position: positie
+ reference: verwijzing
+ csname: naam
+ destination: bestemming
+ triplet: triplet
+ word: woord
+ content: tekst
+\stopmessages
+
+\startmessages english library: setup
+ title: setup
+ formula: formula
+ number: number
+ list: list
+ dimension: dimension
+ mark: mark
+ reference: reference
+ command: command
+ file: file
+ name: name
+ identifier: identifier
+ text: text
+ section: section
+ singular: singular name
+ plural: plural name
+ matrix: n*m
+ see: see
+ inherits: inherits from
+ 1: the characters < and > are globally active!
+ 2: -- is processed
+ 3: -- is undefined
+ 4: -- is processed again
+ optional: optional
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages german library: setup
+ title: Setup
+ formula: Formel
+ number: Nummer
+ list: Liste
+ dimension: Dimension
+ mark: Beschriftung
+ reference: Referenz
+ command: Befehl
+ file: Datei
+ name: Name
+ identifier: Name
+ text: Text
+ section: Abschnitt
+ singular: singular
+ plural: plural
+ matrix: n*m
+ see: siehe
+ inherits: inherits from
+ 1: Die Zeichen < und > gelten global!
+ 2: -- wird verarbeitet
+ 3: -- ist undefiniert
+ 4: -- ist mehrmals verarbeitet
+ optional: optioneel
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages czech library: setup
+ title: setup
+ formula: rovnice
+ number: cislo
+ list: seznam
+ dimension: dimenze
+ mark: znacka
+ reference: reference
+ command: prikaz
+ file: soubor
+ name: jmeno
+ identifier: jmeno
+ text: text
+ section: sekce
+ singular: jmeno v singularu
+ plural: jmeno v pluralu
+ matrix: n*m
+ see: viz
+ inherits: inherits from
+ 1: znaky < a > jsou globalne aktivni!
+ 2: -- je zpracovano
+ 3: -- je nedefinovano
+ 4: -- je zpracovano znovu
+ optional: optioneel
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages italian library: setup
+ title: setup
+ formula: formula
+ number: number
+ list: list
+ dimension: dimension
+ mark: mark
+ reference: reference
+ command: command
+ file: file
+ name: name
+ identifier: name
+ text: text
+ section: section
+ singular: singular name
+ plural: plural name
+ matrix: n*m
+ see: see
+ inherits: inherits from
+ 1: the characters < and > are globally active!
+ 2: -- is processed
+ 3: -- is undefined
+ 4: -- is processed again
+ optional: optioneel
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages romanian library: setup
+ title: setari
+ formula: formula
+ number: numar
+ list: lista
+ dimension: dimensiune
+ mark: marcaj
+ reference: referinta
+ command: comanda
+ file: fisier
+ name: nume
+ identifier: nume
+ text: text
+ section: sectiune
+ singular: nume singular
+ plural: nume pluram
+ matrix: n*m
+ see: vezi
+ inherits: inherits from
+ 1: caracterele < si > sunt active global!
+ 2: este procesat --
+ 3: -- este nedefinit
+ 4: -- este procesat din nou
+ optional: optioneel
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages french library: setup
+ title: réglage
+ formula: formule
+ number: numéro
+ list: liste
+ dimension: dimension
+ mark: marquage
+ reference: reference
+ command: commande
+ file: fichier
+ name: nom
+ identifier: identificateur
+ text: texte
+ section: section
+ singular: nom singulier
+ plural: nom pluriel
+ matrix: n*m
+ see: vois
+ inherits: herite de
+ 1: les caractères < et > sont globalement actifs !
+ 2: -- est traité
+ 3: -- n'est pas défini
+ 4: -- est traité de nouveau
+ optional: optionel
+ displaymath: formule
+ index: entrée
+ math: formule
+ nothing: vide
+ file: fichier
+ position: position
+ reference: réference
+ csname: nom
+ destination: destination
+ triplet: triplet
+ word: mot
+ content: texte
+\stopmessages
+
+\unprotect
+
+% general
+
+\def\setupnumfont {}
+\def\setuptxtfont {}
+\def\setupintfont#1{\uppercase{#1}}
+\def\setupvarfont {\sl}
+\def\setupoptfont {\sl}
+\def\setupalwcolor {}
+\def\setupoptcolor {darkgray}
+
+\defineXMLenvironmentsave [cd:content] [list=,state=]
+ {\simpleSETUPargument{content}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\def\c!setup!internal!#1%
+ {{\setmessagetext{setup}{#1}%
+ \expanded{\setupintfont{\currentmessagetext}}}}
+
+\def\c!setup!text!#1%
+ {{\setmessagetext{setup}{#1}%
+ \setupvarfont{\currentmessagetext}}}
+
+\def\c!setup!command!#1%
+ {{\setupvarfont{\texescape...#1}}}
+
+\def\??stp{@@stp}
+
+\defineregister
+ [texmacro]
+ [texmacros]
+
+\definesorting
+ [texcommand]
+ [texcommands]
+
+\setupsorting
+ [texcommand]
+ [\c!command=\@@stpcommand,
+ \c!criterium=\@@stpcriterium]
+
+\definesorting
+ [eachtexcommand]
+ [alltexcommands]
+
+\setupsorting
+ [eachtexcommand]
+ [\c!command=\@@stpcommand,
+ \c!criterium=\v!all]
+
+\pushmacro\setuptext
+
+\defineframedtext
+ [setuptext]
+ [\c!width=\hsize,
+ \c!height=\v!fit,
+ \c!align=\v!right,
+ \c!offset=0.75em]
+
+\popmacro\setuptext
+
+\newif\ifshortsetup
+
+\def\doshowsetup
+ {\dosingleempty\dodoshowsetup}
+
+\def\dodoshowsetup[#1]%
+ {\iffirstargument
+ \doshowsetup{#1}%
+ \else
+ \expandafter\doshowsetup
+ \fi}
+
+\bgroup \catcode`\<=\active
+
+\gdef\doshowsetup#1%
+ {\bgroup
+ \def<<##1>>{##1}%
+ \edef\ascii{#1}%
+ \enableXML
+ \doifelseXMLelement{stp:\ascii}
+ {\expanded{\flushXMLelement{stp:\ascii}}}
+ {\doifelseXMLelement{stp:\ascii:1}
+ {\expanded{\flushXMLelement{stp:\ascii:1}}}
+ {\defconvertedargument\ascii{#1}%
+ \em unknown setup \quote{\ascii}}}
+ \egroup}
+
+\egroup
+
+\def\setup {\shortsetupfalse\doshowsetup}
+\def\showsetup {\shortsetupfalse\doshowsetup}
+\def\shortsetup{\shortsetuptrue \doshowsetup}
+\def\setupsetup{\dodoubleargument\getparameters[\??stp]}
+
+\setupsetup
+ [\c!before=,
+ \c!after=,
+ \c!command=\setup,
+ \c!criterium=\v!used]
+
+% verwijzing: 0 geen verwijzingen plaatsen / wel genereren
+% 1 alleen bij zie plaatsen / wel genereren
+% 2 alle verwijzingen plaatsen / niet genereren
+% 3 bij zie commando klikken / wel genereren
+
+\setupsetup
+ [\c!reference=0]
+
+\def\placesetup
+ {\bgroup
+ \getvalue{\e!place\e!listof texcommands}%
+ \egroup}
+
+\def\placeallsetups
+ {\bgroup
+ \setupsetup[\c!reference=2]%
+ \setupreferencing[\c!state=\v!stop]%
+ \getvalue{\e!place\e!listof alltexcommands}%
+ \egroup}
+
+\let\placeeverysetup\placeallsetups
+
+\let\plaatssetup \placesetup
+\let\plaatselkesetup\placeallsetups
+
+% we use :1 as fallback
+%
+% \setup{setupinterlinespace}
+% \setup{setupinterlinespace:1}
+% \setup{setupinterlinespace:2}
+
+% todo: make this proper mkiv xml
+
+\defineXMLenvironmentsave [cd:define] [name=]
+ {}
+ {\setxvalue{cd:def:\XMLop{name}}{\XMLflush{cd:define}}}
+
+\defineXMLsingular [cd:resolve] [name=]
+ {\ignorespaces\getvalue{cd:def:\XMLop{name}}\ignorespaces}
+
+\defineXMLenvironment [cd:command] [name=,type=,generated=,interactive=,variant=]
+ {}
+ {\showSETUPrecord}
+
+\def\showSETUPrecord
+ {\getvalue{\e!start setuptext}
+ \tttf
+ \nohyphens
+ \veryraggedright
+ \startXMLmapping [one]
+ \doglobal\newcounter\currentSETUPargument
+ \global\let\maximumSETUPargument\currentSETUPargument
+ \bgroup
+ \doif{\XMLpar{cd:command}{generated}{}}{yes}{\ttsl}%
+ \doifelseXMLop{type}{environment}
+ {\tex{\e!start}}{\tex{}}\ignorespaces
+ \XMLflush{cd:sequence}\ignorespaces
+ \egroup
+ \doifelseXMLempty{cd:arguments}
+ {}
+ {\bgroup
+ \setbox0=\hbox{\XMLflush{cd:arguments}}%
+ \global\let\maximumSETUPargument\currentSETUPargument
+ \doglobal\newcounter\currentSETUPargument
+ \ignorespaces\XMLflush{cd:arguments}%
+ \doif{\XMLpar{cd:command}{type}{}}{environment}
+ {\hskip.5em\unknown\hskip.5em
+ \doif{\XMLpar{cd:command}{generated}{}}{yes}{\ttsl}%
+ \tex{\e!stop}\ignorespaces\XMLflush{cd:sequence}}%
+ \endgraf
+ \egroup
+ %\bgroup
+ % \tx
+ % \doif{\XMLpar{cd:command}{interactive}{}}{yes} {\quad INTERACTIVE}%
+ % \doif{\XMLpar{cd:command}{interactive}{}}{exclusive}{\quad INTERACTIVE ONLY}%
+ %\egroup
+ \startXMLmapping [two]
+ \bgroup
+ \doglobal\newcounter\currentSETUPargument
+ \blank[\v!line]
+ \switchtobodyfont[small] % kan sneller
+ \ignorespaces\XMLflush{cd:arguments}\endgraf
+ \egroup
+ \stopXMLmapping}
+ \stopXMLmapping
+ \getvalue{\e!stop setuptext}}
+
+\defineXMLenvironmentsave [cd:sequence] \ignorespaces \ignorespaces
+\defineXMLenvironmentsave [cd:arguments] \ignorespaces \ignorespaces
+
+%D This is the first pass; here we generate the top line.
+
+\newcounter\currentSETUPargument
+\def\currentSETUPwidth{0pt}
+
+% environmentsave ?
+
+\startXMLmapping [one]
+
+\defineXMLenvironmentsave [cd:string] [value=]
+ {\XMLop{value}\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:variable] [value=]
+ {{\expanded{\setupintfont{\XMLop{value}}}}\ignorespaces}
+ {\ignorespaces}
+
+% moet een standaard type worden
+
+\defineXMLenvironmentsave [cd:assignments] [list=,state=]
+ {\showSETUPassignment\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:keywords] [list=,state=]
+ {\showSETUPkeyword\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:content] [list=,state=]
+ {\showSETUPcontent\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:displaymath] [list=,state=]
+ {\showSETUPdisplaymath\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:index] [list=,state=]
+ {\showSETUPindex\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:math] [list=,state=]
+ {\showSETUPmath\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:nothing] [list=,state=]
+ {\showSETUPnothing\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:file] [list=,state=]
+ {\showSETUPfile\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:position] [list=,state=]
+ {\showSETUPposition\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:reference] [list=,state=]
+ {\showSETUPreference\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:csname] [list=,state=]
+ {\showSETUPcsname\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:destination] [list=,state=]
+ {\showSETUPdestination\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:triplet] [list=,state=]
+ {\showSETUPtriplet\ignorespaces} {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:word] [list=,state=]
+ {\showSETUPword\ignorespaces} {\ignorespaces}
+
+\stopXMLmapping
+
+%D This is the second pass; here we generate the table.
+
+\startXMLmapping [two]
+
+\def\startfirstSETUPcolumn#1%
+ {\bgroup
+ \advance\leftskip 2em
+ \noindent\llap{\hbox to 2em{#1\hss}}}
+
+\def\stopfirstSETUPcolumn
+ {\endgraf
+ \egroup}
+
+\def\startsecondSETUPcolumn#1#2%
+ {\bgroup
+ \advance\hangindent \currentSETUPwidth
+ \advance\hangindent 2.5em
+ \noindent \hbox to \hangindent{#1\hss\hbox to 2.5em{\hss#2\hss}}%
+ \ignorespaces}
+
+\def\stopsecondSETUPcolumn
+ {\endgraf
+ \egroup}
+
+\def\secondSETUPcolumn#1#2%
+ {\startsecondSETUPcolumn{#1}{#2}\stopsecondSETUPcolumn}
+
+\def\previousSETUPargument{\currentSETUPargument}
+
+\defineXMLenvironmentsave [cd:assignments]
+ {}
+ {\xdef\currentSETUPwidth{0pt}%
+ \bgroup
+ \defineXMLenvironment [cd:parameter] [name=]
+ {\setbox0=\hbox{\potentialXMLentity{\XMLop{name}}}%
+ \ifdim\wd0>\currentSETUPwidth\xdef\currentSETUPwidth{\the\wd0}\fi}%
+ {}%
+ \setbox0=\vbox{\XMLflush{cd:assignments}}%
+ \egroup
+ \startfirstSETUPcolumn{\showSETUPnumber}%
+ \doifelseXMLempty{cd:assignments}
+ {\secondSETUPcolumn{\c!setup!text!{see} \previousSETUPargument}{}}
+ {\ignorespaces
+ \XMLflush{cd:assignments}%
+ \let\previousSETUPargument\currentSETUPargument}%
+ \stopfirstSETUPcolumn
+ \blank[\v!halfline]
+ \ignorespaces}
+
+\defineXMLenvironmentsave [cd:keywords] [optional=no]
+ {}
+ {\startfirstSETUPcolumn{\showSETUPnumber}%
+ \doifelseXMLempty{cd:keywords}
+ {\secondSETUPcolumn{see \previousSETUPargument}{}}
+ {\ignorespaces
+ \XMLflush{cd:keywords}%
+ \let\previousSETUPargument\currentSETUPargument}%
+ \stopfirstSETUPcolumn
+ \blank[\v!halfline]
+ \ignorespaces}
+
+\defineXMLenvironment [cd:parameter] [name=]
+ {\startsecondSETUPcolumn{\potentialXMLentity{\XMLop{name}}}{=}%
+ \ignorespaces}
+ {\stopsecondSETUPcolumn
+ \ignorespaces}
+
+\defineXMLenvironmentsave [cd:constant] [type=,default=]
+ {\doifXMLop{default}{yes}{\underbar}%
+ {\potentialXMLentity{\XMLop{type}}}\space\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:variable] [value=]
+ {\potentialXMLentity{\XMLop{value}}\space\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:inherit] [name=]
+ {\secondSETUPcolumn{\c!setup!text!{inherits} \tex{}\XMLop{name}}{}\ignorespaces}
+ {\ignorespaces}
+
+\def\simpleSETUPargument#1%
+ {\startfirstSETUPcolumn{\showSETUPnumber}%
+ \c!setup!internal!{#1}%
+ \stopfirstSETUPcolumn}
+
+\defineXMLenvironmentsave [cd:content] [list=,state=]
+ {\simpleSETUPargument{content}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:displaymath] [list=,state=]
+ {\simpleSETUPargument{display math}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:index] [list=,state=]
+ {\simpleSETUPargument{index}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:math] [list=,state=]
+ {\simpleSETUPargument{math}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:nothing] [list=,state=]
+ {\simpleSETUPargument{nothing}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:file] [list=,state=]
+ {\simpleSETUPargument{file name}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:position] [list=,state=]
+ {\simpleSETUPargument{position}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:reference] [list=,state=]
+ {\simpleSETUPargument{reference}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:csname] [list=,state=]
+ {\simpleSETUPargument{csname}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:destination] [list=,state=]
+ {\simpleSETUPargument{destination}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:triplet] [list=,state=]
+ {\simpleSETUPargument{triplet}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\defineXMLenvironmentsave [cd:word] [list=,state=]
+ {\simpleSETUPargument{word}\blank[\v!halfline]\ignorespaces}
+ {\ignorespaces}
+
+\stopXMLmapping
+
+\defineXMLentity [cd:command] {\c!setup!internal!{command}}
+\defineXMLentity [cd:dimension] {\c!setup!internal!{dimension}}
+\defineXMLentity [cd:file] {\c!setup!internal!{file}}
+\defineXMLentity [cd:name] {\c!setup!internal!{identifier}}
+\defineXMLentity [cd:character] {\c!setup!internal!{character}}
+\defineXMLentity [cd:mark] {\c!setup!internal!{mark}}
+\defineXMLentity [cd:number] {\c!setup!internal!{number}}
+\defineXMLentity [cd:reference] {\c!setup!internal!{reference}}
+\defineXMLentity [cd:plural] {\c!setup!internal!{plural}}
+\defineXMLentity [cd:singular] {\c!setup!internal!{singular}}
+\defineXMLentity [cd:text] {\c!setup!internal!{text}}
+\defineXMLentity [cd:formula] {\c!setup!internal!{formula}}
+\defineXMLentity [cd:file] {\c!setup!internal!{file}}
+\defineXMLentity [cd:matrix] {\c!setup!internal!{matrix}}
+\defineXMLentity [cd:list] {\c!setup!internal!{list}}
+\defineXMLentity [cd:section] {\c!setup!internal!{section}}
+
+\defineXMLentity [cd:noargument] {\c!setup!command!{}}
+\defineXMLentity [cd:oneargument] {\c!setup!command!{\#1}}
+\defineXMLentity [cd:twoarguments] {\c!setup!command!{\#1\#2}}
+\defineXMLentity [cd:threearguments] {\c!setup!command!{\#1\#2\#3}}
+
+%D Todo:
+
+\defineXMLprocess [cd:choice]
+
+%D Auxiliary.
+
+\unexpanded\def\showSETUP#1#2%
+ {\bgroup
+ \doglobal\increment\currentSETUPargument
+ \setbox0=\hbox
+ {\doifelseXMLop{list}{yes}{#2}{#1}}%
+ \setbox2=\hbox to \wd0
+ {\hss
+ \raise1ex\hbox
+ {\tx\ifcase\maximumSETUPargument\relax
+ \or*\else\currentSETUPargument
+ \fi}%
+ \hss}%
+ \setbox4=\hbox to \wd0
+ {\hss
+ \lower2ex\hbox
+ \bgroup
+ \txx\doifXMLop{optional}{yes}{\c!setup!internal!{optional}}%
+ \egroup
+ \hss}%
+ \ht2\ht\strutbox
+ \dp4\dp\strutbox
+ \hskip.5em\hsmash{\box0}\hsmash{\box4}\box2%
+ \egroup}
+
+\def\showSETUPnumber
+ {\doglobal\increment\currentSETUPargument
+ \hbox to 2em
+ {\ifcase\maximumSETUPargument\relax
+ \or*\else\currentSETUPargument
+ \fi
+ \hss}}
+
+\def\showSETUPassignment {\showSETUP
+ {[.\lower.5ex\hbox{=}.]}
+ {[..,.\lower.5ex\hbox{=}.,..]}}
+
+\def\showSETUPkeyword {\showSETUP
+ {[...]}
+ {[...,...]}}
+
+\def\showSETUPargument {\showSETUP
+ {\leftargument..\rightargument}
+ {\leftargument..,...,..\rightargument}}
+
+\def\showSETUPdisplaymath {\showSETUP
+ {\$\$...\$\$}
+ {\$\$...\$\$}}
+
+\def\showSETUPindex {\showSETUP
+ {\leftargument...\rightargument}
+ {\leftargument..+...+..\rightargument}}
+
+\def\showSETUPmath {\showSETUP
+ {\$...\$}
+ {\$...\$}}
+
+\def\showSETUPnothing {\showSETUP
+ {...}
+ {}}
+
+\def\showSETUPfile {\showSETUP
+ {~...~}
+ {}}
+
+\def\showSETUPposition {\showSETUP
+ {(...)}
+ {(...,...)}}
+
+\def\showSETUPreference {\showSETUP
+ {[...]}
+ {[...,...]}}
+
+\def\showSETUPcsname {\showSETUP
+ {{\c!setup!command!{}}}
+ {}}
+
+\def\showSETUPdestination {\showSETUP
+ {[\leftargument..[ref]\rightargument]}
+ {[..,\leftargument..[ref,..]\rightargument,..]}}
+
+\def\showSETUPtriplet {\showSETUP
+ {[x:y:z=]}
+ {[x:y:z=,..]}}
+
+\def\showSETUPword {\showSETUP
+ {\leftargument...\rightargument}
+ {\leftargument.. ... ..\rightargument}}
+
+\def\showSETUPcontent {\showSETUP
+ {\leftargument...\rightargument}
+ {\leftargument.. ... ..\rightargument}}
+
+%\def\c!par!{\c!setup!internal!{endofpar}}
+%\def\c!repeat!{\c!opt!{{\setupvarfont n}*}}
+%\showSETUP\def\c!par!{\texescape par}
+%\showSETUP\def\c!sep!{\texescape\texescape}
+%\def\c!par!{\addtypespec{delimiter}{par}} % \par
+%\def\c!sep!{\addtypespec{separator}{backslash}} % \\
+%\def\c!repeat!{}
+%\def\c!tex!#1{\addtypespec{command}{#1}\doanother{tex}}
+
+\startXMLmapping[zero]
+
+\defineXMLenvironmentsave [cd:command] [name=,type=,generated=,interactive=,variant=]
+ {}
+ {\doifelseXMLop{type}{environment}
+ {\edef\currentSETUPname{start\XMLop{name}}}
+ {\edef\currentSETUPname{\XMLop{name}}}%
+ \doifsomething{\XMLop{variant}}
+ {\edef\currentSETUPname{\currentSETUPname:\XMLop{variant}}}% like setupinterlinespace:1
+ \doifXMLop{generated}{yes}
+ {\edef\currentSETUPname{\currentSETUPname*}}%
+ \doglobal\saveXMLdatainelement{stp:\currentSETUPname}{cd:command}{cd:command}%
+ \expanded{\eachtexcommand[stp:x:\currentSETUPname]{\currentSETUPname}}%
+ \expanded{\texcommand [stp:y:\currentSETUPname]{\currentSETUPname}}}
+
+\stopXMLmapping
+
+\def\loadsetups{\complexorsimple\loadsetups}
+
+\def\simpleloadsetups
+ {\doifnotmode{no-setup-main}
+ {\complexloadsetups[cont-en.xml]}}
+
+\def\complexloadsetups[#1]%
+ {\doifsomething{#1}
+ {\doifnotmode{no-setup-all}
+ {\startXMLmapping[zero]
+ \expanded{\processXMLfilegrouped{#1}}%
+ \stopXMLmapping}}}
+
+\defineXMLsingular [cd:include] [file=]
+ {\complexloadsetups[\XMLop{file}]}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-set-12.mkii b/tex/context/modules/mkii/x-set-12.mkii
new file mode 100644
index 000000000..c2aa265c3
--- /dev/null
+++ b/tex/context/modules/mkii/x-set-12.mkii
@@ -0,0 +1,258 @@
+%D \module
+%D [ file=x-set-12,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Definitions,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[set-11]
+
+\unprotect
+
+% \starttext
+% \setup{installlanguage}
+% \placesetup
+% \stoptext
+
+\definecolor[TitleColor][r=.375,g=.125,b=.125]
+\definecolor[TitleColor][r=.125,g=.375,b=.125]
+\definecolor[TitleColor][r=.125,g=.125,b=.375]
+\definecolor[TitleColor][r=.375,g=.375,b=.125]
+\definecolor[TitleColor][r=.375,g=.125,b=.375]
+\definecolor[TitleColor][r=.125,g=.375,b=.375]
+
+\definecolor[TitleColor][r=.25,g=.20,b=.15]
+\definecolor[TitleColor][r=.25,g=.15,b=.20]
+\definecolor[TitleColor][r=.20,g=.15,b=.25]
+\definecolor[TitleColor][r=.20,g=.25,b=.15]
+\definecolor[TitleColor][r=.15,g=.20,b=.25]
+\definecolor[TitleColor][r=.15,g=.25,b=.20]
+
+\startinterface english \loadsetups[cont-en.xml] \stopinterface
+\startinterface dutch \loadsetups[cont-nl.xml] \stopinterface
+\startinterface german \loadsetups[cont-de.xml] \stopinterface
+\startinterface french \loadsetups[cont-fr.xml] \stopinterface
+\startinterface italian \loadsetups[cont-it.xml] \stopinterface
+\startinterface czech \loadsetups[cont-cs.xml] \stopinterface
+\startinterface romanian \loadsetups[cont-ro.xml] \stopinterface
+
+\startinterface dutch \definecolor[LocalColor][r=.75,g=.25,b=.25] \stopinterface
+\startinterface english \definecolor[LocalColor][r=.25,g=.75,b=.25] \stopinterface
+\startinterface german \definecolor[LocalColor][r=.25,g=.25,b=.75] \stopinterface
+\startinterface french \definecolor[LocalColor][r=.75,g=.75,b=.25] \stopinterface
+\startinterface czech \definecolor[LocalColor][r=.75,g=.25,b=.75] \stopinterface
+\startinterface italian \definecolor[LocalColor][r=.25,g=.75,b=.75] \stopinterface
+\startinterface romanian \definecolor[LocalColor][r=.5,g=.4,b=.3] \stopinterface
+% \definecolor[LocalColor][r=.5,g=.3,b=.4]
+% \definecolor[LocalColor][r=.4,g=.3,b=.5]
+% \definecolor[LocalColor][r=.4,g=.5,b=.3]
+% \definecolor[LocalColor][r=.3,g=.4,b=.5]
+% \definecolor[LocalColor][r=.3,g=.5,b=.4]
+
+\startinterface english \definecolor[TitleColor][r=.375,g=.125,b=.125] \stopinterface
+\startinterface dutch \definecolor[TitleColor][r=.125,g=.375,b=.125] \stopinterface
+\startinterface german \definecolor[TitleColor][r=.125,g=.125,b=.375] \stopinterface
+\startinterface french \definecolor[TitleColor][r=.375,g=.375,b=.125] \stopinterface
+\startinterface italian \definecolor[TitleColor][r=.375,g=.125,b=.375] \stopinterface
+\startinterface czech \definecolor[TitleColor][r=.125,g=.375,b=.375] \stopinterface
+\startinterface romanian \definecolor[TitleColor][r=.25,g=.20,b=.15] \stopinterface
+% \definecolor[TitleColor][r=.25,g=.15,b=.20]
+% \definecolor[TitleColor][r=.20,g=.15,b=.25]
+% \definecolor[TitleColor][r=.20,g=.25,b=.15]
+% \definecolor[TitleColor][r=.15,g=.20,b=.25]
+% \definecolor[TitleColor][r=.15,g=.25,b=.20]
+
+\definecolor [lightgray] [s=.9]
+\definecolor [darkgray] [s=.1]
+
+\usetypescript[palatino]
+\setupbodyfont[palatino,9pt]
+
+\setupcolors
+ [\c!state=\v!start]
+
+\defineoverlay
+ [cover]
+ [\hbox to \paperwidth{\hss\reuseMPgraphic{cover+back}}]
+
+\defineoverlay
+ [back]
+ [\hbox to \paperwidth{\reuseMPgraphic{cover+back}\hss}]
+
+\startreusableMPgraphic{cover+back}
+ numeric h, w ; path p, q, r ; color f, d ; pair s ;
+ h := OverlayHeight ; w := 2*OverlayWidth ;
+ r := unitsquare xyscaled (w,h) ;
+ fill r withcolor \MPcolor{lightgray} ;
+ set_grid(w,h,w/8,w/16) ;
+ forever :
+ s := center r randomized (w,h) ;
+ if new_on_grid(xpart s, ypart s) :
+ s := (dx,dy) ;
+ p := fullsquare xyscaled(w/4,w/8) ;
+ q := (-4w,ypart ulcorner p) --
+ .5[ulcorner p, urcorner p] --
+ (4w,ypart urcorner p) ;
+ q := q shifted (0,-w/24) ;
+ p := p randomized (w/40,w/40) ;
+ q := q randomized (0,w/100) ;
+ q := q cutafter (p cutafter point 3 of p) ;
+ q := q cutbefore (p cutbefore point 3 of p) ;
+ d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ;
+ f := \MPcolor{lightgray} randomized (.5,.9) ;
+ pickup pencircle scaled (w/100) ;
+ fill p shifted s withcolor f ;
+ draw p shifted s withcolor d ;
+ draw q shifted s withcolor d ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+ setbounds currentpicture to r ;
+\stopreusableMPgraphic
+
+\definelayout
+ [titlepage]
+ [\c!backspace=1cm,
+ \c!topspace=1cm,
+ \c!width=\v!middle,
+ \c!height=\v!middle,
+ \c!header=0pt,
+ \c!footer=0pt]
+
+\setuplayout
+ [\c!backspace=2cm,
+ \c!topspace=1.5cm,
+ \c!header=0cm,
+ \c!footer=0cm,
+ \c!width=\v!middle,
+ \c!height=\v!middle]
+
+\setuppagenumbering
+ [\c!alternative=\v!doublesided]
+
+\setupsetup
+ [\c!criterium=\v!all,
+ \c!reference=0]
+
+\setupframedtexts
+ [setuptext]
+ [\c!frame=\v!on,
+ \c!rulethickness=1pt,
+ \c!framecolor=TitleColor]
+
+\setupunderbar
+ [\c!rulethickness=1pt,
+ \c!rulecolor=TitleColor]
+
+\starttext
+
+\setupbackgrounds
+ [\v!rightpage]
+ [\c!background=cover]
+
+\setuplayout
+ [titlepage]
+
+\startsetups text:commands
+ \startinterface dutch \strut commando's \par \stopinterface
+ \startinterface english \strut commands \par \stopinterface
+ \startinterface german \strut befehle \par \stopinterface
+ \startinterface french \strut commandes \par \stopinterface
+ \startinterface czech \strut p\v{r}ikazy \par \stopinterface
+ \startinterface italian \strut comandi \par \stopinterface
+ \startinterface romanian \strut comenzile \par \stopinterface
+\stopsetups
+
+\startsetups text:uppercase
+ \startinterface dutch NL\stopinterface
+ \startinterface english EN\stopinterface
+ \startinterface german DE\stopinterface
+ \startinterface french FR\stopinterface
+ \startinterface czech CS\stopinterface
+ \startinterface italian IT\stopinterface
+ \startinterface romanian RO\stopinterface
+\stopsetups
+
+\startsetups text:lowercase
+ \startinterface dutch \strut nl / nederlands \par \stopinterface
+ \startinterface english \strut en / english \par \stopinterface
+ \startinterface german \strut de / deutsch \par \stopinterface
+ \startinterface french \strut fr / fran\c{c}ais \par \stopinterface
+ \startinterface czech \strut cs / \v{c}esk\'y \par \stopinterface
+ \startinterface italian \strut it / italiano \par \stopinterface
+ \startinterface romanian \strut ro / rom\^{a}n\u{a} \par \stopinterface
+\stopsetups
+
+\startmakeup[\v!standard]
+ \dontcomplain
+ \setupalign[\v!left]
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 150pt]\setstrut
+ \setups[text:uppercase]
+ \stopcolor
+\stopmakeup
+
+\setuplayout % needed ?
+
+\setupbackgrounds
+ [\v!rightpage]
+ [\c!background=]
+
+\startmakeup[\v!standard]
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \setupalign[\v!left]
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setups[text:lowercase]
+ \par \strut \currentdate \par
+ \stopcolor
+\stopmakeup
+
+\protect
+
+\placeeverysetup
+
+\unprotect
+
+\page[\v!yes,\v!blank,\v!right,\v!left]
+
+\setuplayout
+ [titlepage]
+
+\setupbackgrounds
+ [\v!leftpage]
+ [\c!background=back]
+
+\startmakeup[\v!standard][\c!page=]
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setupalign[\v!left]
+ \vfill
+ PRAGMA ADE \par
+ Ridderstraat 27 \par
+ 8061GH Hasselt NL \par
+ www.pragma-ade.com \par
+ \stopcolor
+\stopmakeup
+
+\protect
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-sm2om.xsl b/tex/context/modules/mkii/x-sm2om.xsl
new file mode 100644
index 000000000..93e1a12c5
--- /dev/null
+++ b/tex/context/modules/mkii/x-sm2om.xsl
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ This style sheet is used in the Math4All project. This project
+ will provide an on-line math method for secondary and tertiary
+ education. In addition to the web-bases content the project
+ provides high quality typeset output as well.
+
+ This style converts some elements to open math alternatives and
+ its sole purpose is to easy the input of inline math.
+
+ <i>x</i> identifier (use <v>x</v> when possible)
+ <n>5</n> number
+ <v>5</v> variable
+ <r>1:2</r> interval (range)
+ <r>x:y</r> interval (range) using variables
+
+ This style is dedicated to Frits Spijkers, an open minded math
+ author who patiently tested all the related TeX things.
+
+ Hans Hagen, PRAGMA ADE, Hasselt NL / 2006-04-27
+
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output method="xml"/>
+
+ <xsl:template match="processing-instruction()"><xsl:copy/><xsl:text>
+ </xsl:text></xsl:template>
+
+ <xsl:template match="node()|@*" >
+ <xsl:copy>
+ <xsl:apply-templates select = "node()|@*" />
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="comment"></xsl:template>
+
+ <xsl:variable name='openmath-to-content-mathml'><value-of select='$stylesheet-path'/>/x-openmath.xsl</xsl:variable>
+
+ <xsl:template name='om-minus'>
+ <OMS cd="arith1" name="unary_minus"/>
+ </xsl:template>
+ <xsl:template name='om-infinity'>
+ <OMS cd="nums1" name="infinity"/>
+ </xsl:template>
+ <xsl:template name='om-interval-oo'>
+ <OMS cd="interval1" name="interval_oo"/>
+ </xsl:template>
+ <xsl:template name='om-interval-oc'>
+ <OMS cd="interval1" name="interval_oc"/>
+ </xsl:template>
+ <xsl:template name='om-interval-co'>
+ <OMS cd="interval1" name="interval_co"/>
+ </xsl:template>
+ <xsl:template name='om-interval-cc'>
+ <OMS cd="interval1" name="interval_cc"/>
+ </xsl:template>
+
+ <xsl:template name='om-kind-of-data'>
+ <xsl:param name='arg'/>
+ <xsl:choose>
+ <xsl:when test="contains($arg,'/')">
+ <xsl:element name="OMA">
+ <xsl:element name="OMS">
+ <xsl:attribute name="cd">nums1</xsl:attribute>
+ <xsl:attribute name="name">rational</xsl:attribute>
+ </xsl:element>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-before($arg,'/')"/>
+ </xsl:call-template>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-after($arg,'/')"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="contains($arg,'.') or contains($arg,',')">
+ <xsl:element name="OMF">
+ <xsl:attribute name="dec"><xsl:value-of select="$arg"/></xsl:attribute>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="number($arg)">
+ <xsl:choose>
+ <xsl:when test="contains($arg,'-')">
+ <xsl:element name="OMA">
+ <xsl:call-template name='om-minus'/>
+ <xsl:element name="OMI">
+ <xsl:value-of select="substring-after($arg,'-')"/>
+ </xsl:element>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="contains($arg,'+')">
+ <xsl:element name="OMI">
+ <xsl:value-of select="substring-after($arg,'+')"/>
+ </xsl:element>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:element name="OMI">
+ <xsl:value-of select="$arg"/>
+ </xsl:element>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:element name="OMV">
+ <xsl:attribute name="name"><xsl:value-of select="$arg"/></xsl:attribute>
+ </xsl:element>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match='i|n'>
+ <xsl:element name="OMOBJ">
+ <xsl:attribute name="style">inline</xsl:attribute>
+ <xsl:attribute name="xmlns">http://www.openmath.org/OpenMath</xsl:attribute>
+ <xsl:attribute name="version">2.0</xsl:attribute>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="text()"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template match='v'>
+ <xsl:element name="OMOBJ">
+ <xsl:attribute name="style">inline</xsl:attribute>
+ <xsl:attribute name="xmlns">http://www.openmath.org/OpenMath</xsl:attribute>
+ <xsl:attribute name="version">2.0</xsl:attribute>
+ <xsl:element name="OMV">
+ <xsl:attribute name="name"><xsl:apply-templates/></xsl:attribute>
+ </xsl:element>
+ </xsl:element>
+ </xsl:template>
+
+ <!-- r a/b split in two parts -->
+
+ <xsl:template match='r'>
+ <xsl:element name="OMOBJ">
+ <xsl:attribute name="style">inline</xsl:attribute>
+ <xsl:attribute name="xmlns">http://www.openmath.org/OpenMath</xsl:attribute>
+ <xsl:attribute name="version">2.0</xsl:attribute>
+ <xsl:element name="OMA">
+ <xsl:variable name='type'>
+ <xsl:choose>
+ <xsl:when test="@type=''">
+ cc
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@type"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="@type='io'">
+ <xsl:call-template name='om-interval-oo'/>
+ <xsl:element name="OMA">
+ <xsl:call-template name='om-minus'/>
+ <xsl:call-template name='om-infinity'/>
+ </xsl:element>
+ <xsl:element name="OMI">
+ <xsl:call-template name='om-kind-of-data'>
+ <xsl:with-param name='arg' select='text()'/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="@type='oi'">
+ <xsl:call-template name='om-interval-oo'/>
+ <xsl:element name="OMI">
+ <xsl:call-template name='om-kind-of-data'>
+ <xsl:with-param name='arg' select='text()'/>
+ </xsl:call-template>
+ </xsl:element>
+ <xsl:call-template name='om-infinity'/>
+ </xsl:when>
+ <xsl:when test="@type='ic'">
+ <xsl:call-template name='om-interval-oc'/>
+ <xsl:element name="OMA">
+ <xsl:call-template name='om-minus'/>
+ <xsl:call-template name='om-infinity'/>
+ </xsl:element>
+ <xsl:element name="OMI">
+ <xsl:call-template name='om-kind-of-data'>
+ <xsl:with-param name='arg' select='text()'/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:when>
+ <xsl:when test="@type='ci'">
+ <xsl:call-template name='om-interval-co'/>
+ <xsl:element name="OMI">
+ <xsl:call-template name='om-kind-of-data'>
+ <xsl:with-param name='arg' select='text()'/>
+ </xsl:call-template>
+ </xsl:element>
+ <xsl:call-template name='om-infinity'/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:element name="OMS">
+ <xsl:attribute name="cd">interval1</xsl:attribute>
+ <xsl:attribute name="name">interval_<xsl:value-of select="$type"/></xsl:attribute>
+ </xsl:element>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-before(text(),':')"/>
+ </xsl:call-template>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-after(text(),':')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:element>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template match='c'>
+ <xsl:element name="OMOBJ">
+ <xsl:attribute name="style">inline</xsl:attribute>
+ <xsl:attribute name="xmlns">http://www.openmath.org/OpenMath</xsl:attribute>
+ <xsl:attribute name="version">2.0</xsl:attribute>
+ <xsl:element name="OMA">
+ <xsl:element name="OMS">
+ <xsl:attribute name="cd">linalg3</xsl:attribute>
+ <xsl:attribute name="name">vector</xsl:attribute>
+ </xsl:element>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-before(text(),':')"/>
+ </xsl:call-template>
+ <xsl:call-template name="om-kind-of-data">
+ <xsl:with-param name='arg' select="substring-after(text(),':')"/>
+ </xsl:call-template>
+ </xsl:element>
+ </xsl:element>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tex/context/modules/mkii/x-steps.mkii b/tex/context/modules/mkii/x-steps.mkii
new file mode 100644
index 000000000..47141699a
--- /dev/null
+++ b/tex/context/modules/mkii/x-steps.mkii
@@ -0,0 +1,85 @@
+%D \module
+%D [ file=m-steps,
+%D version=2001.05.28,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Step Charts \& Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The \XML\ interface:
+
+\usemodule[m][steps]
+
+\unprotect
+
+\defineXMLdirective [stepchart] [charts] \setupSTEPcharts
+\defineXMLdirective [stepchart] [cells] \setupSTEPcells
+\defineXMLdirective [stepchart] [texts] \setupSTEPtexts
+\defineXMLdirective [stepchart] [lines] \setupSTEPlines
+
+\defineXMLdirective [steptable] [tables] \setupSTEPtables
+\defineXMLdirective [steptable] [cells] \setupSTEPcells
+\defineXMLdirective [steptable] [texts] \setupSTEPtexts
+\defineXMLdirective [steptable] [lines] \setupSTEPlines
+
+\defineXMLpickup[stepchart][@@STPC]
+ {\bgroup
+ \defineXMLpush[top]%
+ \defineXMLpush[bot]%
+ \defineXMLenvironment[lines][@@STEL]
+ {\expanded{\startlines[\theXMLarguments{@@STEL}]}}
+ {\stoplines}%
+ \defineXMLenvironment[cells][@@STEC]
+ {\XMLerase{top}\XMLerase{bot}}
+ {\expanded{\cells[\theXMLarguments{@@STEC}]{\XMLpop{top}}{\XMLpop{bot}}}}%
+ \defineXMLenvironment[texts][@@STET]
+ {\XMLerase{top}\XMLerase{bot}}
+ {\expanded{\texts[\theXMLarguments{@@STET}]{\XMLpop{top}}{\XMLpop{bot}}}}%
+ \defineXMLenvironmentpush[cell][@@STEC]
+ {\XMLerase{cell}}
+ {\expanded{\cell [\theXMLarguments{@@STEC}]{\XMLpop{cell}}}}%
+ \defineXMLenvironmentpush [text] [@@STET]
+ {\XMLerase{text}}
+ {\expanded{\text [\theXMLarguments{@@STET}]{\XMLpop{text}}}}%
+ \expanded{\startSTEPchart[\theXMLarguments{@@STPC}]}}
+ {\stopSTEPchart
+ \egroup}
+
+\defineXMLpickup[steptable][@@STPT]
+ {\bgroup
+ \defineXMLenvironment[lines][@@STEL]
+ {\expanded{\startlines[\theXMLarguments{@@STEL}]}}
+ {\stoplines}%
+ \defineXMLargument[cell][@@STEC]
+ {\expanded{\cell[\theXMLarguments{@@STEC}]}}%
+ \defineXMLargument[text][@@STET]
+ {\expanded{\text[\theXMLarguments{@@STET}]}}%
+ \defineXMLargument[prep]
+ {\prep}%
+ \expanded{\startSTEPtable[\theXMLarguments{@@STPT}]}}
+ {\stopSTEPtable
+ \egroup}
+
+\defineXMLpickup[stepaligntable][@@STPT]
+ {\bgroup
+ \defineXMLenvironment[lines][@@STEL]
+ {\expanded{\setupSTEPlines[\theXMLarguments{@@STEL}]}}
+ {}%
+ \defineXMLpush[c1]\defineXMLpush[c2]\defineXMLpush[c3]%
+ \defineXMLenvironment[cells][@@STEC]
+ {\XMLerase{c1}\XMLerase{c1}\XMLerase{c3}}
+ {\expanded{\cells[\theXMLarguments{@@STEC}]{\XMLpop{c1}}{\XMLpop{c2}}{\XMLpop{c3}}}}%
+ \defineXMLargument[text][@@STET]
+ {\expanded{\text[\theXMLarguments{@@STET}]}}%
+ \defineXMLargument[prep]
+ {\prep}%
+ \expanded{\startSTEPaligntable[\theXMLarguments{@@STPT}]}}
+ {\stopSTEPaligntable
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/modules/mkii/x-xml-01.mkii b/tex/context/modules/mkii/x-xml-01.mkii
new file mode 100644
index 000000000..95ce51fc8
--- /dev/null
+++ b/tex/context/modules/mkii/x-xml-01.mkii
@@ -0,0 +1,91 @@
+%D \module
+%D [ file=x-xml-01,
+%D version=2001.10.10,
+%D title=\CONTEXT\ XML Style File,
+%D subtitle=Formatting X?? files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% texexec --use=xml-format yourfile.x** [--mode=packed,wide]
+%
+% pdftotext yourfile.pdf yournewfile.x**
+
+\doifnothing {\inputfilename} {\end}
+\doiffileelse {\inputfilename} {} {\end}
+
+% The following makes pdftotext too slow:
+%
+% \definepapersize
+% [mine]
+% [height=.99\maxdimen,
+% width=200cm]
+%
+% \setuppapersize
+% [mine]
+% [mine]
+%
+% \setupbodyfont
+% [0.4pt,tt]
+%
+% this is faster
+%
+% \setuppapersize
+% [A0][A0]
+%
+% but normal A4 combined with 1 pt font size is the best
+%
+% An alternative is to use a small size, but this leads to
+% too many messages
+%
+% \setupbodyfont
+% [1pt,tt]
+%
+% so we stick to a more normal alternive.
+
+\unprotect
+
+\setuplayout
+ [\c!backspace=0cm,
+ \c!topspace=0cm,
+ %\c!width=40em,
+ \c!width=\v!middle,
+ \c!height=\v!middle,
+ \c!header=0cm,
+ \c!footer=0cm]
+
+\setupbodyfont [tt,10pt]
+\setuptolerance [\v!verytolerant]
+\setupalign [\v!broad,\v!right]
+\setupXMLfile [\c!level=2]
+
+\startmode[wide]
+
+ \setuplayout [\c!width=250cm]
+
+\stopmode
+
+\startmode[packed]
+
+% \setupXMLfile [inbetween=]
+ \setupXMLfile [\c!tussen=]
+
+\stopmode
+
+\protect
+
+% The main text:
+
+\def\XMLbannerprocessor#1{\string<\string ?xml #1\string ?\string>\endgraf}
+
+\defineXMLprocessor [xml] {\XMLbannerprocessor}
+
+\starttext
+
+ \dontcomplain \showXMLfile{\inputfilename}
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-xml-02.mkii b/tex/context/modules/mkii/x-xml-02.mkii
new file mode 100644
index 000000000..e33ab9ee4
--- /dev/null
+++ b/tex/context/modules/mkii/x-xml-02.mkii
@@ -0,0 +1,91 @@
+%D \module
+%D [ file=x-xml-02,
+%D version=2001.10.10,
+%D title=\CONTEXT\ XML Style File,
+%D subtitle=Pretty Printing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% texexec --use=xml-pretty yourfile.x** [--mode=letter]
+
+\doifnothing {\inputfilename} {\end}
+\doiffileelse {\inputfilename} {} {\end}
+
+\startmode[letter]
+ \setuppapersize[letter][letter]
+\stopmode
+
+\setuplayout
+ [backspace=1.5cm,
+ topspace=1.5cm,
+ bottomspace=1cm,
+ width=middle,
+ height=middle,
+ header=1.5cm,
+ footer=1.5cm]
+
+\setupcolors
+ [state=local]
+
+\setuppagenumbering
+ [location=]
+
+\setuplayout
+ [style=type]
+
+\setupbodyfont
+ [10pt,tt]
+
+\setuptolerance
+ [verytolerant]
+
+\setupalign
+ [broad,right]
+
+\lowercasestring\inputfilename \to \lcinputfilename
+\defconvertedcommand\lcinputfilename\lcinputfilename % make _ safe
+
+\setupheadertexts
+ [\lcinputfilename]
+
+\setupfootertexts
+ [\currentdate\space\string| \currenttime\space \string| \pagenumber]
+
+% let's have a look at the type of content:
+
+\setupXMLfile
+ [level=2]
+
+\startmode[*suffix-xml]
+ % ok
+\stopmode
+
+\startmode[*suffix-rng]
+ \showXMLlin[value]
+\stopmode
+
+\startmode[*suffix-rlg]
+ \showXMLlin
+ [rl:type,rl:state,rl:name,rl:suffix,rl:label,rl:file,rl:original,
+ rl:width,rl:height,rl:base,rl:page]
+\stopmode
+
+\startmode[*suffix-exa]
+ \showXMLlin
+ [exa:resolve,exa:include]
+\stopmode
+
+\def\XMLbannerprocessor#1{\string<\string ?xml #1\string ?\string>\endgraf}
+
+\defineXMLprocessor [xml] {\XMLbannerprocessor}
+
+\starttext
+
+\showXMLfile{\inputfilename}
+
+\stoptext
diff --git a/tex/context/modules/mkii/x-xml-11.mkii b/tex/context/modules/mkii/x-xml-11.mkii
new file mode 100644
index 000000000..047561370
--- /dev/null
+++ b/tex/context/modules/mkii/x-xml-11.mkii
@@ -0,0 +1,134 @@
+%D \module
+%D [ file=x-xml-11,
+%D version=2004.09.16,
+%D title=\CONTEXT\ XML Style File,
+%D subtitle=Formatting X?? files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% xmltools --analyze yourfile.xml
+% texexec --use=xml-analyze yourfile.*
+
+% \doifnothing {\inputfilename} {\end}
+% \doiffileelse {\inputfilename} {} {\end}
+
+\doifnothing {\jobfullname} {\end}
+\doiffileelse {\jobfullname} {} {\end}
+
+\useXMLfilter[ent]
+\useXMLfilter[utf]
+
+\chardef\XMLtokensreduction\plustwo
+
+\definehead
+ [SomeElement]
+ [subsection]
+
+\setuphead
+ [SomeElement]
+ [ownnumber=yes,
+ style=\tfb,
+ numberstyle=\tfxx,
+ alternative=margin]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=2cm,
+ cutspace=1cm,
+ topspace=1cm,
+ header=0pt]
+
+\setupfootertexts
+ [\jobfullname] % [\inputfilename]
+
+\usetypescript[modern][texnansi] \setupbodyfont[modern,tt,10pt]
+
+\defineXMLenvironment
+ [document]
+ {}
+ {}
+
+\defineXMLpickup
+ [entities][n=0]
+ {\expanded{\SomeElement{\XMLop{n}}{Entities}}
+ \starttabulate[|l|l|l|]}
+ {\stoptabulate}
+
+\defineXMLcommand % ugly hack (make macro of it)
+ [entity][name=,n=0]
+ {\startexpanded
+ \noexpand \NC \XMLop{name}
+ \noexpand \NC \XMLop{n}
+ \noexpand \NC \noexpand\doXMLentity\XMLop{name};
+ \noexpand \NC
+ \noexpand \NR
+ \stopexpanded}
+
+\defineXMLpickup
+ [characters][n=0]
+ {\expanded{\SomeElement{\XMLop{n}}{Characters}}
+ \bgroup
+ \let\nonbreakablespace\empty % messes up the table
+ \starttabulate[|l|r|r|l|l|l|l|]}
+ {\stoptabulate
+ \egroup}
+
+% todo: narrowtt
+
+\defineXMLcommand
+ [character][number=,utf=,n=0,uname=,pname=,cname=]
+ {\startexpanded
+ \noexpand \NC \noexpand \unicodehexnumber{\XMLop{number}}
+ \noexpand \NC \XMLop{number}
+ \noexpand \NC \XMLop{n}
+ \noexpand \NC \noexpand \unicodechar {\XMLop{number}}
+ \noexpand \NC \tx \lowercase\expandafter{\XMLop{uname}}
+ \noexpand \NC \tx \noexpand \unicodepair {\XMLop{number}}
+ \noexpand \NC \tx \XMLop{cname}
+ \noexpand \NC
+ \noexpand \NR
+ \stopexpanded}
+
+\defineXMLenvironment
+ [elements]
+ {}
+ {}
+
+\newtoks \TabulateToks
+
+\defineXMLpickup
+ [element][name=,n=0]
+ {\expanded{\SomeElement{\XMLop{n}}{\XMLop{name}}}
+ \TabulateToks\emptytoks}
+ {\starttabulate[|l|r|p|]
+ \the\TabulateToks
+ \stoptabulate}
+
+\defineXMLenvironment
+ [attribute][name=]
+ {\xdef\AttributeName{\XMLop{name}}}
+ {}
+
+\defineXMLenvironment
+ [instance][value=,n=0]
+ {\appendetoks
+ \noexpand \NC \AttributeName
+ \noexpand \NC \XMLop{n}
+ \noexpand \NC \XMLop{value}
+ \noexpand \NC
+ \noexpand \NR
+ \to \TabulateToks}
+ {\xdef\AttributeName{}}
+
+\starttext
+
+% \processXMLfilegrouped{\inputfilename}
+\processXMLfilegrouped{\jobfullname}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-barcodes.mkiv b/tex/context/modules/mkiv/m-barcodes.mkiv
new file mode 100644
index 000000000..e4c43b376
--- /dev/null
+++ b/tex/context/modules/mkiv/m-barcodes.mkiv
@@ -0,0 +1,122 @@
+%D \module
+%D [ file=m-barcodes,
+%D version=2010.03.14,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Barcodes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{barcodes}{the 'zint' module is a better choice}
+
+% \startTEXpage
+% \startPSTRICKS
+% \pspicture(-4mm,-1mm)(38mm,26mm)
+% \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}%
+% \endpspicture
+% \stopPSTRICKS
+% \stopTEXpage
+
+% 978-94-90688-01-1
+%
+% 978 = ean isbn identifier (979 also)
+% 94 = country code
+% 90688 = publisher code
+% 01 = title 1
+% 1 = checksum
+
+\usemodule[pstricks]
+
+\usePSTRICKSmodule[pst-barcode]
+
+\definefont[barcodefont][file:ocrb10]
+% \definefont[barcodefont][file:texgyreheros-regular]
+
+\startluacode
+moduledata.barcodes = { }
+
+local function split(code)
+ local t = { string.byte(code,1,#code) }
+ if #t >= 12 then
+ local s = 0
+ for i=1,11,2 do
+ s = s + (t[i]-48)
+ end
+ for i=2,12,2 do
+ s = s + 3 * (t[i]-48)
+ end
+ local m = s % 10
+ local c = (m > 0 and (10 - m)) or 0
+ return t, s, m, c
+ end
+end
+
+function moduledata.barcodes.isbn_1(original)
+ local code = string.gsub(original,"%-","")
+ local t, s, m, c = split(code)
+ if t then
+ if #t == 13 then
+ local e = ((c == t[13] - 48) and "correct") or "wrong"
+ logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s, status=%s",original,s,m,c,e)
+ else
+ logs.report("isbn code","code=%s, sum=%s, checksum=%s, modulo=%s",original,s,m,c)
+ code= code .. c
+ end
+ end
+ context(code)
+end
+
+function moduledata.barcodes.isbn_2(original)
+ local code = string.gsub(original,"%-","")
+ local t, s, m, c = split(code)
+ if t and #t == 12 then
+ original = original .. "-" .. c
+ end
+ context(original)
+end
+\stopluacode
+
+\startsetups barcode:isbn
+ \scale
+ [width=5cm]
+ {
+ \vbox {
+ \hbox {
+ \hskip3.7mm
+ \scale[width=34mm]{\barcodefont ISBN \ctxlua{moduledata.barcodes.isbn_2("\getvariable{barcode}{code}")}}
+ }
+ \par
+ \normalexpanded { \noexpand \setPSTRICKS {
+ \noexpand \pspicture(-4mm,-1mm)(38mm,26mm)
+ \noexpand \psbarcode {
+ \ctxlua{moduledata.barcodes.isbn_1("\getvariable{barcode}{code}")}
+ } {
+ includetext guardwhitespace
+ } {
+ ean13
+ }
+ \noexpand \endpspicture
+ }
+ \noexpand \processPSTRICKS }
+ }
+ }
+\stopsetups
+
+\unexpanded\def\barcode[#1]%
+ {\bgroup
+ \setvariables[barcode][type=isbn,#1]%
+ \directsetup{barcode:\getvariable{barcode}{type}}%
+ \egroup}
+
+\continueifinputfile{m-barcodes.mkiv}
+
+\starttext
+ \startTEXpage
+ \barcode[type=isbn,code=978-94-90688-01-1]
+ \stopTEXpage
+\stoptext
+
diff --git a/tex/context/modules/mkiv/m-chart.lua b/tex/context/modules/mkiv/m-chart.lua
new file mode 100644
index 000000000..f1e7f4cb9
--- /dev/null
+++ b/tex/context/modules/mkiv/m-chart.lua
@@ -0,0 +1,945 @@
+if not modules then modules = { } end modules ['x-flow'] = {
+ version = 1.001,
+ comment = "companion to m-flow.mkvi",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- when we can resolve mpcolor at the lua end we will
+-- use metapost.graphic(....) directly
+
+-- todo: labels
+
+moduledata.charts = moduledata.charts or { }
+
+local gsub, match, find, format, lower = string.gsub, string.match, string.find, string.format, string.lower
+local setmetatableindex = table.setmetatableindex
+local P, S, C, Cc, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.match
+
+local report_chart = logs.reporter("chart")
+
+local variables = interfaces.variables
+
+local v_yes = variables.yes
+local v_no = variables.no
+local v_none = variables.none
+local v_standard = variables.standard
+local v_overlay = variables.overlay
+local v_round = variables.round
+local v_test = variables.test
+
+local defaults = {
+ chart = {
+ name = "",
+ option = "",
+ backgroundcolor = "",
+ width = 100*65536,
+ height = 50*65536,
+ dx = 30*65536,
+ dy = 30*65536,
+ offset = 0,
+ bodyfont = "",
+ dot = "",
+ hcompact = variables_no,
+ vcompact = variables_no,
+ autofocus = "",
+ focus = "",
+ labeloffset = 5*65536,
+ commentoffset = 5*65536,
+ exitoffset = 0,
+
+ },
+ shape = { -- FLOS
+ rulethickness = 65536,
+ default = "",
+ framecolor = "darkblue",
+ backgroundcolor = "lightgray",
+ },
+ focus = { -- FLOF
+ rulethickness = 65536,
+ framecolor = "darkred",
+ backgroundcolor = "gray",
+ },
+ line = { -- FLOL
+ rulethickness = 65536,
+ radius = 10*65536,
+ color = "darkgreen",
+ corner = "",
+ dash = "",
+ arrow = "",
+ offset = "",
+ },
+ set = { -- FLOX
+ },
+ split = {
+ nx = 3,
+ ny = 3,
+ command = "",
+ marking = "",
+ before = "",
+ after = "",
+ }
+}
+
+local validshapes = {
+ ["node"] = { kind = "shape", number = 0 },
+ ["action"] = { kind = "shape", number = 24 },
+ ["procedure"] = { kind = "shape", number = 5 },
+ ["product"] = { kind = "shape", number = 12 },
+ ["decision"] = { kind = "shape", number = 14 },
+ ["archive"] = { kind = "shape", number = 19 },
+ ["loop"] = { kind = "shape", number = 35 },
+ ["wait"] = { kind = "shape", number = 6 },
+ ["subprocedure"] = { kind = "shape", number = 20 },
+ ["singledocument"] = { kind = "shape", number = 32 },
+ ["multidocument"] = { kind = "shape", number = 33 },
+
+ ["right"] = { kind = "line", number = 66 },
+ ["left"] = { kind = "line", number = 67 },
+ ["up"] = { kind = "line", number = 68 },
+ ["down"] = { kind = "line", number = 69 },
+}
+
+local validlabellocations = {
+ l = "l", left = "l",
+ r = "r", right = "r",
+ t = "t", top = "t",
+ b = "b", bottom = "b",
+ lt = "lt",
+ rt = "rt",
+ lb = "lb",
+ rb = "rb",
+ tl = "tl",
+ tr = "tr",
+ bl = "bl",
+ br = "br",
+}
+
+local validcommentlocations = {
+ l = "l", left = "l",
+ r = "r", right = "r",
+ t = "t", top = "t",
+ b = "b", bottom = "b",
+ lt = "lt",
+ rt = "rt",
+ lb = "lb",
+ rb = "rb",
+ tl = "tl",
+ tr = "tr",
+ bl = "bl",
+ br = "br",
+}
+
+local validtextlocations = {
+ l = "l", left = "l",
+ r = "r", right = "r",
+ t = "t", top = "t",
+ b = "b", bottom = "b",
+ c = "c", center = "c",
+ m = "c", middle = "m",
+ lt = "lt",
+ rt = "rt",
+ lb = "lb",
+ rb = "rb",
+ tl = "lt",
+ tr = "rt",
+ bl = "lb",
+ br = "rb",
+}
+
+setmetatableindex(validshapes,function(t,k)
+ local l = gsub(lower(k)," ","")
+ local v = rawget(t,l)
+ if not v then
+ local n = tonumber(k)
+ if n then
+ v = { kind = "shape", number = n }
+ else
+ v = rawget(t,"action")
+ end
+ end
+ t[k] = v
+ return v
+end)
+
+local charts = { }
+
+local data, hash, temp, last_x, last_y, name
+
+function commands.flow_start_chart(chartname)
+ data = { }
+ hash = { }
+ last_x, last_y = 0, 0
+ name = chartname
+end
+
+function commands.flow_stop_chart()
+ charts[name] = {
+ data = data,
+ hash = hash,
+ last_x = last_x,
+ last_y = last_y,
+ }
+ data, hash, temp = nil, nil, nil
+end
+
+-- function commands.flow_set(chartname,chartdata)
+-- local hash = { }
+-- local data = { }
+-- charts[name] = {
+-- data = data,
+-- hash = hash,
+-- }
+-- for i=1,#chartdata do
+-- local di = data[i]
+-- local name = di.name or ""
+-- if name then
+-- data[#data+1] = {
+-- name = name,
+-- labels = di.labels or { },
+-- comments = di.comments or { },
+-- exits = di.exits or { },
+-- connections = di.connections or { },
+-- settings = di.settings or { },
+-- x = di.x or 1,
+-- y = di.y or 1,
+-- }
+-- hash[name] = i
+-- end
+-- end
+-- end
+
+function commands.flow_reset(chartname)
+ charts[name] = nil
+end
+
+function commands.flow_set_current_cell(n)
+ temp = data[tonumber(n)] or { }
+end
+
+function commands.flow_start_cell(settings)
+ temp = {
+ texts = { },
+ labels = { },
+ exits = { },
+ connections = { },
+ settings = settings,
+ x = 1,
+ y = 1,
+ realx = 1,
+ realy = 1,
+ name = "",
+ }
+end
+
+function commands.flow_stop_cell()
+ data[#data+1] = temp
+ hash[temp.name or #data] = temp
+end
+
+function commands.flow_set_name(str)
+ temp.name = str
+end
+
+function commands.flow_set_shape(str)
+ temp.shape = str
+end
+
+function commands.flow_set_destination(str)
+ temp.destination = str
+end
+
+function commands.flow_set_text(align,str)
+ temp.texts[#temp.texts+1] = {
+ location = align,
+ text = str,
+ }
+end
+
+function commands.flow_set_overlay(str)
+ temp.overlay = str
+end
+
+function commands.flow_set_focus(str)
+ temp.focus = str
+end
+
+function commands.flow_set_figure(str)
+ temp.figure = str
+end
+
+function commands.flow_set_label(location,text)
+ temp.labels[#temp.labels+1] = {
+ location = location,
+ text = text,
+ }
+end
+
+function commands.flow_set_comment(location,text)
+ local connections = temp.connections
+ if connections then
+ local connection = connections[#connections]
+ if connection then
+ local comments = connection.comments
+ if comments then
+ comments[#comments+1] = {
+ location = location,
+ text = text,
+ }
+ end
+ end
+ end
+end
+
+function commands.flow_set_exit(location,text)
+ temp.exits[#temp.exits+1] = {
+ location = location,
+ text = text,
+ }
+end
+
+function commands.flow_set_include(name,x,y,settings)
+ data[#data+1] = {
+ include = name,
+ x = x,
+ y = y,
+ -- settings = settings,
+ }
+end
+
+local function inject(includedata,data,hash)
+ local subchart = charts[includedata.include]
+ if not subchart then
+ return
+ end
+ local subdata = subchart.data
+ if not subdata then
+ return
+ end
+ local xoffset = (includedata.x or 1) - 1
+ local yoffset = (includedata.y or 1) - 1
+ local settings = includedata.settings
+ for i=1,#subdata do
+ local si = subdata[i]
+ if si.include then
+ inject(si,data,hash)
+ else
+ local x = si.x + xoffset
+ local y = si.y + yoffset
+ local t = {
+ x = x,
+ y = y,
+ realx = x,
+ realy = y,
+ settings = settings,
+ }
+ setmetatableindex(t,si)
+ data[#data+1] = t
+ hash[si.name or #data] = t
+ end
+ end
+end
+
+local function pack(data,field)
+ local list, max = { }, 0
+ for e=1,#data do
+ local d = data[e]
+ local f = d[field]
+ list[f] = true
+ if f > max then
+ max = f
+ end
+ end
+ for i=1,max do
+ if not list[i] then
+ for e=1,#data do
+ local d = data[e]
+ local f = d[field]
+ if f > i then
+ d[field] = f - 1
+ end
+ end
+ end
+ end
+end
+
+local function expanded(chart,chartsettings)
+ local expandeddata = { }
+ local expandedhash = { }
+ local expandedchart = {
+ data = expandeddata,
+ hash = expandedhash,
+ }
+ setmetatableindex(expandedchart,chart)
+ local data = chart.data
+ local hash = chart.hash
+ for i=1,#data do
+ local di = data[i]
+ if di.include then
+ inject(di,expandeddata,expandedhash)
+ else
+ expandeddata[#expandeddata+1] = di
+ expandedhash[di.name or #expandeddata] = di
+ end
+ end
+ --
+ expandedchart.settings = chartsettings or { }
+ -- make locals
+ chartsettings.shape = chartsettings.shape or { }
+ chartsettings.focus = chartsettings.focus or { }
+ chartsettings.line = chartsettings.line or { }
+ chartsettings.set = chartsettings.set or { }
+ chartsettings.split = chartsettings.split or { }
+ chartsettings.chart = chartsettings.chart or { }
+ setmetatableindex(chartsettings.shape,defaults.shape)
+ setmetatableindex(chartsettings.focus,defaults.focus)
+ setmetatableindex(chartsettings.line ,defaults.line )
+ setmetatableindex(chartsettings.set ,defaults.set )
+ setmetatableindex(chartsettings.split,defaults.split)
+ setmetatableindex(chartsettings.chart,defaults.chart)
+ --
+ if chartsettings.chart.vcompact == v_yes then
+ pack(expandeddata,"y")
+ end
+ if chartsettings.chart.hcompact == v_yes then
+ pack(expandeddata,"x")
+ end
+ --
+ for i=1,#expandeddata do
+ local cell = expandeddata[i]
+ local settings = cell.settings
+ if not settings then
+ cell.settings = chartsettings
+ else
+ settings.shape = settings.shape or { }
+ settings.focus = settings.focus or { }
+ settings.line = settings.line or { }
+ setmetatableindex(settings.shape,chartsettings.shape)
+ setmetatableindex(settings.focus,chartsettings.focus)
+ setmetatableindex(settings.line ,chartsettings.line)
+ end
+ end
+ return expandedchart
+end
+
+local splitter = lpeg.splitat(",")
+
+function commands.flow_set_location(x,y)
+ if type(x) == "string" and not y then
+ x, y = lpegmatch(splitter,x)
+ end
+ if not x or x == "" then
+ x = last_x
+ elseif type(x) == "number" then
+ -- ok
+ elseif x == "+" then
+ x = last_x + 1
+ elseif x == "-" then
+ x = last_x - 1
+ elseif find(x,"^[%+%-]") then
+ x = last_x + (tonumber(x) or 0)
+ else
+ x = tonumber(x)
+ end
+ if not y or y == "" then
+ y = last_y
+ elseif type(y) == "number" then
+ -- ok
+ elseif y == "+" then
+ y = last_y + 1
+ elseif x == "-" then
+ y = last_y - 1
+ elseif find(y,"^[%+%-]") then
+ y = last_y + (tonumber(y) or 0)
+ else
+ y = tonumber(y)
+ end
+ temp.x = x or 1
+ temp.y = y or 1
+ temp.realx = x or 1
+ temp.realy = y or 1
+ last_x = x or last_x
+ last_y = y or last_y
+end
+
+function commands.flow_set_connection(location,displacement,name)
+ local dx, dy = lpegmatch(splitter,displacement)
+ dx = tonumber(dx)
+ dy = tonumber(dy)
+ temp.connections[#temp.connections+1] = {
+ location = location,
+ dx = dx or 0,
+ dy = dy or 0,
+ name = name,
+ comments = { },
+ }
+end
+
+local function visible(chart,cell)
+ local x, y = cell.x, cell.y
+ return
+ x >= chart.from_x and x <= chart.to_x and
+ y >= chart.from_y and y <= chart.to_y and cell
+end
+
+local function process_cells(chart,xoffset,yoffset)
+ local data = chart.data
+ if not data then
+ return
+ end
+ local focus = utilities.parsers.settings_to_hash(chart.settings.chart.focus or "")
+ for i=1,#data do
+ local cell = visible(chart,data[i])
+ if cell then
+ local settings = cell.settings
+ local shapesettings = settings.shape
+ local shape = cell.shape
+ if not shape or shape == "" then
+ shape = shapesettings.default or "none"
+ end
+ if shape ~= v_none then
+ local shapedata = validshapes[shape]
+ context("flow_begin_sub_chart ;") -- when is this needed
+ if shapedata.kind == "line" then
+ local linesettings = settings.line
+ context("flow_shape_line_color := \\MPcolor{%s} ;", linesettings.color)
+ context("flow_shape_fill_color := \\MPcolor{%s} ;", linesettings.backgroundcolor)
+ context("flow_shape_line_width := %p ; ", linesettings.rulethickness)
+ elseif focus[cell.focus] or focus[cell.name] then
+ local focussettings = settings.focus
+ context("flow_shape_line_color := \\MPcolor{%s} ;", focussettings.framecolor)
+ context("flow_shape_fill_color := \\MPcolor{%s} ;", focussettings.backgroundcolor)
+ context("flow_shape_line_width := %p ; ", focussettings.rulethickness)
+ else
+ local shapesettings = settings.shape
+ context("flow_shape_line_color := \\MPcolor{%s} ;", shapesettings.framecolor)
+ context("flow_shape_fill_color := \\MPcolor{%s} ;", shapesettings.backgroundcolor)
+ context("flow_shape_line_width := %p ; " , shapesettings.rulethickness)
+ end
+ context("flow_peepshape := false ;") -- todo
+ context("flow_new_shape(%s,%s,%s) ;",cell.x+xoffset,cell.y+yoffset,shapedata.number)
+ context("flow_end_sub_chart ;")
+ end
+ end
+ end
+end
+
+-- todo : make lpeg for splitter
+
+local sign = S("+p") / "1"
+ + S("-m") / "-1"
+
+local full = C(P("left"))
+ + C(P("right"))
+ + C(P("top"))
+ + C(P("bottom"))
+
+local char = P("l") / "left"
+ + P("r") / "right"
+ + P("t") / "top"
+ + P("b") / "bottom"
+
+local space = P(" ")^0
+
+local what = space
+ * (sign + Cc("0"))
+ * space
+ * (full + char)
+ * space
+ * (sign + Cc("0"))
+ * space
+ * (full + char)
+ * space
+ * P(-1)
+
+-- print(lpegmatch(what,"lr"))
+-- print(lpegmatch(what,"+l+r"))
+-- print(lpegmatch(what,"+l"))
+-- print(lpegmatch(what,"+ left+r "))
+
+local function process_connections(chart,xoffset,yoffset)
+ local data = chart.data
+ local hash = chart.hash
+ if not data then
+ return
+ end
+ local settings = chart.settings
+ for i=1,#data do
+ local cell = visible(chart,data[i])
+ if cell then
+ local connections = cell.connections
+ for j=1,#connections do
+ local connection = connections[j]
+ local othername = connection.name
+ local othercell = hash[othername]
+ if othercell then -- and visible(chart,data[i]) then
+ local cellx, celly = cell.x, cell.y
+ local otherx, othery, location = othercell.x, othercell.y, connection.location
+ if otherx > 0 and othery > 0 and cellx > 0 and celly > 0 and connection.location then
+ local what_cell, where_cell, what_other, where_other = lpegmatch(what,location)
+ if what_cell and where_cell and what_other and where_other then
+ local linesettings = settings.line
+ context("flow_smooth := %s ;", linesettings.corner == v_round and "true" or "false")
+ context("flow_dashline := %s ;", linesettings.dash == v_yes and "true" or "false")
+ context("flow_arrowtip := %s ;", linesettings.arrow == v_yes and "true" or "false")
+ context("flow_touchshape := %s ;", linesettings.offset == v_none and "true" or "false")
+ context("flow_dsp_x := %s ; flow_dsp_y := %s ;",connection.dx or 0, connection.dy or 0)
+ context("flow_connection_line_color := \\MPcolor{%s} ;",linesettings.color)
+ context("flow_connection_line_width := %p ;",linesettings.rulethickness)
+ context("flow_connect_%s_%s (%s) (%s,%s,%s) (%s,%s,%s) ;",where_cell,where_other,j,cellx,celly,what_cell,otherx,othery,what_other)
+ context("flow_dsp_x := 0 ; flow_dsp_y := 0 ;")
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+local texttemplate = "\\setvariables[flowcell:text][x=%s,y=%s,text={%s},align={%s},figure={%s},destination={%s}]"
+
+local splitter = lpeg.splitat(":")
+
+local function process_texts(chart,xoffset,yoffset)
+ local data = chart.data
+ local hash = chart.hash
+ if not data then
+ return
+ end
+ for i=1,#data do
+ local cell = visible(chart,data[i])
+ if cell then
+ local x = cell.x or 1
+ local y = cell.y or 1
+ local texts = cell.texts
+ for i=1,#texts do
+ local text = texts[i]
+ local data = text.text
+ local align = validlabellocations[text.align or ""] or text.align or ""
+ local figure = i == 1 and cell.figure or ""
+ local destination = i == 1 and cell.destination or ""
+ context('flow_chart_draw_text(%s,%s,textext("%s")) ;',x,y,format(texttemplate,x,y,data,align,figure,destination))
+ end
+ local labels = cell.labels
+ for i=1,#labels do
+ local label = labels[i]
+ local text = label.text
+ local location = validlabellocations[label.location or ""] or label.location or ""
+ if text and location then
+ context('flow_chart_draw_label(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text)
+ end
+ end
+ local exits = cell.exits
+ for i=1,#exits do
+ local exit = exits[i]
+ local text = exit.text
+ local location = validlabellocations[exit.location or ""]
+ if text and location then
+ -- maybe make autoexit an option
+ if location == "l" and x == chart.from_x + 1 or
+ location == "r" and x == chart.to_x - 1 or
+ location == "t" and y == chart.to_y - 1 or
+ location == "b" and y == chart.from_y + 1 then
+ context('flow_chart_draw_exit(%s,%s,"%s",textext("\\strut %s")) ;',x,y,location,text)
+ end
+ end
+ end
+ local connections = cell.connections
+ for i=1,#connections do
+ local comments = connections[i].comments
+ for j=1,#comments do
+ local comment = comments[j]
+ local text = comment.text
+ local location = comment.location or ""
+ local length = 0
+ -- "tl" "tl:*" "tl:0.5"
+ local loc, len = lpegmatch(splitter,location) -- do the following in lpeg
+ if len == "*" then
+ location = validcommentlocations[loc] or ""
+ if location == "" then
+ location = "*"
+ else
+ location = location .. ":*"
+ end
+ elseif loc then
+ location = validcommentlocations[loc] or "*"
+ length = tonumber(len) or 0
+ else
+ location = validcommentlocations[location] or ""
+ end
+ if text and location then
+ context('flow_chart_draw_comment(%s,%s,%s,"%s",%s,textext("\\strut %s")) ;',x,y,i,location,length,text)
+ end
+ end
+ end
+ end
+ end
+end
+
+local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny)
+ if not settings then
+ print("no settings given")
+ return
+ end
+ local chartname = settings.chart.name
+ if not chartname then
+ print("no name given")
+ return
+ end
+ local chart = charts[chartname]
+ if not chart then
+ print("no such chart",chartname)
+ return
+ end
+-- chart = table.copy(chart)
+ chart = expanded(chart,settings)
+ local chartsettings = chart.settings.chart
+ local autofocus = chart.settings.chart.autofocus
+ if autofocus then
+ autofocus = utilities.parsers.settings_to_hash(autofocus)
+ if not next(autofocus) then
+ autofocus = false
+ end
+ end
+ -- check natural window
+ local x = forced_x or tonumber(chartsettings.x)
+ local y = forced_y or tonumber(chartsettings.y)
+ local nx = forced_nx or tonumber(chartsettings.nx)
+ local ny = forced_ny or tonumber(chartsettings.ny)
+ --
+ local minx, miny, maxx, maxy = 0, 0, 0, 0
+ local data = chart.data
+ for i=1,#data do
+ local cell = data[i]
+ if not autofocus or autofocus[cell.name] then -- offsets probably interfere with autofocus
+ local x = cell.x
+ local y = cell.y
+ if minx == 0 or x < minx then minx = x end
+ if miny == 0 or y < miny then miny = y end
+ if minx == 0 or x > maxx then maxx = x end
+ if miny == 0 or y > maxy then maxy = y end
+ end
+ end
+ -- print("1>",x,y,nx,ny)
+ -- print("2>",minx, miny, maxx, maxy)
+ -- check of window should be larger (maybe autofocus + nx/ny?)
+ if autofocus then
+ -- x and y are ignored
+ if nx and nx > 0 then
+ maxx = minx + nx - 1
+ end
+ if ny and ny > 0 then
+ maxy = miny + ny - 1
+ end
+ else
+ if x and x > 0 then
+ minx = x
+ end
+ if y and y > 0 then
+ miny = y
+ end
+ if nx and nx > 0 then
+ maxx = minx + nx - 1
+ end
+ if ny and ny > 0 then
+ maxy = miny + ny - 1
+ end
+ end
+-- print("3>",minx, miny, maxx, maxy)
+ --
+ local nx = maxx - minx + 1
+ local ny = maxy - miny + 1
+ -- relocate cells
+ for i=1,#data do
+ local cell = data[i]
+ cell.x = cell.realx - minx + 1
+ cell.y = cell.realy - miny + 1
+ end
+ chart.from_x = 1
+ chart.from_y = 1
+ chart.to_x = nx
+ chart.to_y = ny
+ chart.nx = nx
+ chart.ny = ny
+ --
+ chart.shift_x = minx + 1
+ chart.shift_y = miny + 1
+ --
+ return chart
+end
+
+local function makechart(chart)
+ local settings = chart.settings
+ local chartsettings = settings.chart
+ --
+ context.begingroup()
+ context.forgetall()
+ --
+ context.startMPcode()
+ context("if unknown context_flow : input mp-char.mpiv ; fi ;")
+ context("flow_begin_chart(0,%s,%s);",chart.nx,chart.ny)
+ --
+ if chartsettings.option == v_test or chartsettings.dot == v_yes then
+ context("flow_show_con_points := true ;")
+ context("flow_show_mid_points := true ;")
+ context("flow_show_all_points := true ;")
+ elseif chartsettings.dot ~= "" then -- no checking done, private option
+ context("flow_show_%s_points := true ;",chartsettings.dot)
+ end
+ --
+ local backgroundcolor = chartsettings.backgroundcolor
+ if backgroundcolor and backgroundcolor ~= "" then
+ context("flow_chart_background_color := \\MPcolor{%s} ;",backgroundcolor)
+ end
+ --
+ local shapewidth = chartsettings.width
+ local gridwidth = shapewidth + 2*chartsettings.dx
+ local shapeheight = chartsettings.height
+ local gridheight = shapeheight + 2*chartsettings.dy
+ local chartoffset = chartsettings.offset
+ local labeloffset = chartsettings.labeloffset
+ local exitoffset = chartsettings.exitoffset
+ local commentoffset = chartsettings.commentoffset
+ context("flow_grid_width := %p ;", gridwidth)
+ context("flow_grid_height := %p ;", gridheight)
+ context("flow_shape_width := %p ;", shapewidth)
+ context("flow_shape_height := %p ;", shapeheight)
+ context("flow_chart_offset := %p ;", chartoffset)
+ context("flow_label_offset := %p ;", labeloffset)
+ context("flow_exit_offset := %p ;", exitoffset)
+ context("flow_comment_offset := %p ;", commentoffset)
+ --
+ local radius = settings.line.radius
+ local rulethickness = settings.line.rulethickness
+ local dx = chartsettings.dx
+ local dy = chartsettings.dy
+ if radius < rulethickness then
+ radius = 2.5*rulethickness
+ if radius > dx then
+ radius = dx
+ end
+ if radius > dy then
+ radius = dy
+ end
+ end
+ context("flow_connection_line_width := %p ;", rulethickness)
+ context("flow_connection_smooth_size := %p ;", radius)
+ context("flow_connection_arrow_size := %p ;", radius)
+ context("flow_connection_dash_size := %p ;", radius)
+ --
+ local offset = chartsettings.offset -- todo: pass string
+ if offset == v_none or offset == v_overlay or offset == "" then
+ offset = -2.5 * radius -- or rulethickness?
+ elseif offset == v_standard then
+ offset = radius -- or rulethickness?
+ end
+ context("flow_chart_offset := %p ;",offset)
+ --
+ context("flow_reverse_y := true ;")
+ process_cells(chart,0,0)
+ process_connections(chart,0,0)
+ process_texts(chart,0,0)
+ -- context("clip_chart(%s,%s,%s,%s) ;",x,y,nx,ny) -- todo: draw lines but not shapes
+ context("flow_end_chart ;")
+ context.stopMPcode()
+ context.endgroup()
+end
+
+local function splitchart(chart)
+ local settings = chart.settings
+ local splitsettings = settings.split
+ local chartsettings = settings.chart
+ --
+ local name = chartsettings.name
+ --
+ local from_x = chart.from_x
+ local from_y = chart.from_y
+ local to_x = chart.to_x
+ local to_y = chart.to_y
+ --
+ local step_x = splitsettings.nx or to_x
+ local step_y = splitsettings.ny or to_y
+ local delta_x = splitsettings.dx or 0
+ local delta_y = splitsettings.dy or 0
+ --
+ report_chart("spliting %a from (%s,%s) upto (%s,%s) with steps (%s,%s) and overlap (%s,%s)",
+ name,from_x,from_y,to_x,to_y,step_x,step_y,delta_x,delta_y)
+ --
+ local part_x = 0
+ local first_x = from_x
+ while true do
+ part_x = part_x + 1
+ local last_x = first_x + step_x - 1
+ local done = last_x >= to_x
+ if done then
+ last_x = to_x
+ end
+-- if first_x >= to_x then
+-- break
+-- end
+ local part_y = 0
+ local first_y = from_y
+ while true do
+ part_y = part_y + 1
+ local last_y = first_y + step_y - 1
+ local done = last_y >= to_y
+ if done then
+ last_y = to_y
+ end
+-- if first_y >= to_y then
+-- break
+-- end
+ --
+local data = chart.data
+for i=1,#data do
+ local cell = data[i]
+-- inspect(cell)
+ local cx, cy = cell.x, cell.y
+ if cx >= first_x and cx <= last_x then
+ if cy >= first_y and cy <= last_y then
+ report_chart("part (%s,%s) of %a is split from (%s,%s) -> (%s,%s)",part_x,part_y,name,first_x,first_y,last_x,last_y)
+ local x = first_x
+ local y = first_y
+ local nx = last_x - first_x + 1
+ local ny = last_y - first_y + 1
+ context.beforeFLOWsplit()
+ context.handleFLOWsplit(function()
+ makechart(getchart(settings,x,y,nx,ny)) -- we need to pass frozen settings !
+ end)
+ context.afterFLOWsplit()
+ break
+ end
+ end
+end
+ --
+ if done then
+ break
+ else
+ first_y = last_y + 1 - delta_y
+ end
+ end
+ if done then
+ break
+ else
+ first_x = last_x + 1 - delta_x
+ end
+ end
+end
+
+function commands.flow_make_chart(settings)
+ local chart = getchart(settings)
+ if chart then
+ local settings = chart.settings
+ if settings then
+ local chartsettings = settings.chart
+ if chartsettings and chartsettings.split == v_yes then
+ splitchart(chart)
+ else
+ makechart(chart)
+ end
+ else
+ makechart(chart)
+ end
+ end
+end
diff --git a/tex/context/modules/mkiv/m-chart.mkvi b/tex/context/modules/mkiv/m-chart.mkvi
new file mode 100644
index 000000000..a0c8b2244
--- /dev/null
+++ b/tex/context/modules/mkiv/m-chart.mkvi
@@ -0,0 +1,540 @@
+%D \module
+%D [ file=m-chart,
+%D version=2011.10.1, % 1998.10.10,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Flow Charts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo (if used):
+% flowsets
+% autoscaling (bodyfontsteps)
+% comment
+% overlay
+%
+% todo:
+% \useFLOWchart[name][parent][setting,setting][additional settings]
+% \useFLOWchart[name][parent][additional settings]
+% setups
+% mp instance with less files
+
+\registerctxluafile{m-chart}{}
+
+\unprotect
+
+% todo: figure out a nice way to define the lot: share current and
+% support current as name (nb: we need to set parent then)
+
+\installcorenamespace {flowchart} % \def\??flch{@@flch} % chart
+\installcorenamespace {flowline} % \def\??flln{@@flln} % line
+\installcorenamespace {flowshape} % \def\??flsh{@@flsh} % shape
+\installcorenamespace {flowfocus} % \def\??flfc{@@flfc} % focus
+\installcorenamespace {flowsets} % \def\??flst{@@flst} % sets
+\installcorenamespace {flowsplit} % \def\??flsp{@@flsp} % split
+
+\installsimplecommandhandler \??flowchart {FLOWchart} \??flowchart % maybe just a setuphandler
+\installsimplecommandhandler \??flowline {FLOWline} \??flowline % maybe just a setuphandler
+\installsimplecommandhandler \??flowshape {FLOWshape} \??flowshape % maybe just a setuphandler
+\installsimplecommandhandler \??flowfocus {FLOWfocus} \??flowfocus % maybe just a setuphandler
+\installsimplecommandhandler \??flowsets {FLOWsets} \??flowsets % maybe just a setuphandler
+\installsimplecommandhandler \??flowsplit {FLOWsplit} \??flowsplit % maybe just a setuphandler
+
+\let\setupFLOWcharts\setupFLOWchart
+\let\setupFLOWlines \setupFLOWline
+\let\setupFLOWshapes\setupFLOWshape
+\let\setupFLOWsets \setupFLOWset
+
+\setupFLOWcharts
+ [\c!width=12\bodyfontsize,
+ \c!height=7\bodyfontsize,
+ \c!offset=\FLOWlineparameter\c!rulethickness,
+ \c!dx=2\bodyfontsize,
+ \c!dy=2\bodyfontsize,
+ \c!nx=0,
+ \c!ny=0,
+ \c!x=1,
+ \c!y=1,
+ \c!labeloffset=.5\bodyfontsize,
+ \c!commentoffset=.5\bodyfontsize,
+ \c!exitoffset=\zeropoint,
+ % \c!split=\v!no,
+ % \c!maxwidth=,
+ % \c!maxheight=,
+ % \c!option=,
+ % \c!bodyfont=,
+ % \c!dot=, % private option
+ % \c!autofocus=,
+ % \c!focus=,
+ % \c!background=,
+ % \c!framecolor=
+ % \c!backgroundcolor=, % \s!white
+ \c!rulethickness=.15\bodyfontsize, %\linewidth,
+ \c!frame=\v!off]
+
+\setupFLOWlines
+ [\c!corner=\v!round,
+ \c!arrow=\v!yes,
+ \c!dash=\v!no,
+ \c!radius=.375\bodyfontsize,
+ \c!color=FLOWlinecolor,
+ \c!rulethickness=.15\bodyfontsize,
+ \c!offset=\zeropoint]
+
+\setupFLOWshapes
+ [\c!default=action,
+ \c!framecolor=FLOWframecolor,
+ \c!background=\v!color,
+ \c!backgroundcolor=FLOWbackgroundcolor,
+ \c!rulethickness=.15\bodyfontsize,
+ \c!offset=.5\bodyfontsize]
+
+\setupFLOWfocus
+ [\c!framecolor=FLOWfocuscolor,
+ \c!background=\FLOWshapeparameter\c!background,
+ \c!backgroundcolor=\FLOWshapeparameter\c!backgroundcolor,
+ \c!rulethickness=\FLOWshapeparameter\c!rulethickness,
+ \c!offset=\FLOWshapeparameter\c!offset]
+
+\setupFLOWsplit
+ [\c!dx=0,
+ \c!dy=0,
+ % \c!command=,
+ % \c!before=,
+ % \c!after=,
+ \c!nx=3,
+ \c!ny=4]
+
+\unexpanded\def\beforeFLOWsplit{\FLOWsplitparameter\c!before}
+\unexpanded\def\afterFLOWsplit {\FLOWsplitparameter\c!after}
+\unexpanded\def\handleFLOWsplit{\FLOWsplitparameter\c!command}
+
+\definecolor [FLOWfocuscolor] [s=.2]
+\definecolor [FLOWlinecolor] [s=.5]
+\definecolor [FLOWframecolor] [s=.7]
+\definecolor [FLOWbackgroundcolor] [s=.9]
+
+\newtoks\everyFLOWchart
+
+\unexpanded\def\module_charts_process[#name]%
+ {\ctxcommand{flow_start_chart("#name")}}
+
+\unexpanded\def\startFLOWchart
+ {\startnointerference
+ \the\everyFLOWchart
+ \dosingleempty\module_charts_start_chart}
+
+\unexpanded\def\module_charts_start_chart[#name]%
+ {\ctxcommand{flow_start_chart("#name")}}
+
+\unexpanded\def\stopFLOWchart
+ {\ctxcommand{flow_stop_chart()}%
+ \stopnointerference}
+
+\unexpanded\def\defineFLOWchart % for old times sake
+ {\dodoubleempty\module_charts_FLOW_define}
+
+\unexpanded\def\module_charts_FLOW_define[#name][#settings]#cells% todo: save settings
+ {\startnointerference
+ \the\everyFLOWchart
+ \ctxcommand{flow_start_chart("#name")}%
+ #cells%
+ \ctxcommand{flow_stop_chart()}%
+ \stopnointerference}
+
+\unexpanded\def\startFLOWcell
+ {\dodoubleempty\module_charts_start_cell}
+
+\unexpanded\def\module_charts_start_cell[#1][#2]%
+ {\begingroup
+ \iffirstargument
+ \setupFLOWshape[#1]%
+ \fi
+ \ifsecondargument
+ \setupFLOWline[#2]%
+ \fi
+ \ctxcommand{flow_start_cell {
+ shape = {
+ rulethickness = \number\dimexpr\FLOWshapeparameter\c!rulethickness,
+ default = "\FLOWshapeparameter\c!default",
+ framecolor = "\FLOWshapeparameter\c!framecolor",
+ backgroundcolor = "\FLOWshapeparameter\c!backgroundcolor",
+ },
+ focus = {
+ rulethickness = \number\dimexpr\FLOWfocusparameter\c!rulethickness,
+ framecolor = "\FLOWfocusparameter\c!framecolor",
+ backgroundcolor = "\FLOWfocusparameter\c!backgroundcolor",
+ },
+ line = {
+ rulethickness = \number\dimexpr\FLOWlineparameter\c!rulethickness,
+ radius = \number\dimexpr\FLOWlineparameter\c!radius,
+ color = "\FLOWlineparameter\c!color",
+ corner = "\FLOWlineparameter\c!corner",
+ dash = "\FLOWlineparameter\c!dash",
+ arrow = "\FLOWlineparameter\c!arrow",
+ offset = \number\dimexpr\FLOWlineparameter\c!offset,
+ },
+ } }%
+ \endgroup}
+
+\unexpanded\def\stopFLOWcell
+ {\ctxcommand{flow_stop_cell()}}
+
+\unexpanded\def\FLOWchart
+ {\dodoubleempty\module_charts_process}
+
+\def\module_charts_process[#name][#settings]%
+ {\bgroup % \vbox removed
+ \insidefloattrue
+ \dontcomplain
+ \setupFLOWchart[#settings]%
+ \usebodyfontparameter\FLOWchartparameter
+ \ctxcommand{flow_make_chart {
+ chart = {
+ name = "#name",
+ option = "\FLOWchartparameter\c!option",
+ backgroundcolor = "\FLOWchartparameter\c!backgroundcolor",
+ width = \number\dimexpr\FLOWchartparameter\c!width,
+ height = \number\dimexpr\FLOWchartparameter\c!height,
+ dx = \number\dimexpr\FLOWchartparameter\c!dx,
+ dy = \number\dimexpr\FLOWchartparameter\c!dy,
+ offset = \number\dimexpr\FLOWchartparameter\c!offset,
+ % bodyfont = "\FLOWchartparameter\c!bodyfont",
+ dot = "\FLOWchartparameter\c!dot", % private option
+ hcompact = "\FLOWchartparameter\c!hcompact", % undocumented option
+ vcompact = "\FLOWchartparameter\c!vcompact", % undocumented option
+ focus = "\FLOWchartparameter\c!focus",
+ autofocus = "\FLOWchartparameter\c!autofocus",
+ nx = "\FLOWchartparameter\c!nx",
+ ny = "\FLOWchartparameter\c!ny",
+ x = "\FLOWchartparameter\c!x",
+ y = "\FLOWchartparameter\c!y",
+ labeloffset = \number\dimexpr\FLOWchartparameter\c!labeloffset,
+ commentoffset = \number\dimexpr\FLOWchartparameter\c!commentoffset,
+ exitoffset = \number\dimexpr\FLOWchartparameter\c!exitoffset,
+ split = "\FLOWchartparameter\c!split",
+ },
+ shape = {
+ rulethickness = \number\dimexpr\FLOWshapeparameter\c!rulethickness,
+ default = "\FLOWshapeparameter\c!default",
+ framecolor = "\FLOWshapeparameter\c!framecolor",
+ backgroundcolor = "\FLOWshapeparameter\c!backgroundcolor",
+ },
+ focus = {
+ rulethickness = \number\dimexpr\FLOWfocusparameter\c!rulethickness,
+ framecolor = "\FLOWfocusparameter\c!framecolor",
+ backgroundcolor = "\FLOWfocusparameter\c!backgroundcolor",
+ },
+ line = {
+ rulethickness = \number\dimexpr\FLOWlineparameter\c!rulethickness,
+ radius = \number\dimexpr\FLOWlineparameter\c!radius,
+ color = "\FLOWlineparameter\c!color",
+ corner = "\FLOWlineparameter\c!corner",
+ dash = "\FLOWlineparameter\c!dash",
+ arrow = "\FLOWlineparameter\c!arrow",
+ offset = "\FLOWlineparameter\c!offset",
+ },
+ set = {
+ },
+ split = {
+ nx = \number\FLOWsplitparameter\c!nx,
+ ny = \number\FLOWsplitparameter\c!ny,
+ dx = \number\FLOWsplitparameter\c!dx,
+ dy = \number\FLOWsplitparameter\c!dy,
+ command = "",
+ marking = "\FLOWsplitparameter\c!marking",
+ before = "",
+ after = "",
+ }
+ } }%
+ \egroup}
+
+\unexpanded\def\FLOWcharts
+ {\dodoubleempty\FLOW_charts}
+
+\def\FLOW_charts[#name][#settings]
+ {\begingroup
+ \setupFLOWchart[\c!split=\v!yes]%
+ \setupFLOWsplit[#settings]%
+ \module_charts_process[#name][]% \FLOWchart...
+ \endgroup}
+
+\appendtoks
+ \let\name \FLOW_name
+ \let\shape \FLOW_shape
+ \let\destination\FLOW_destination
+ \let\focus \FLOW_focus
+ \let\overlay \FLOW_overlay
+ \let\location \FLOW_location
+ \let\text \FLOW_text
+ \let\label \FLOW_label
+ \let\comment \FLOW_comment
+ \let\exit \FLOW_exit
+ \let\connection \FLOW_connection
+ \let\include \FLOW_include
+ \let\figure \FLOW_figure
+ %
+ \let\connect \FLOW_connection
+ \let\locate \FLOW_location
+ %
+ \let\includeFLOWchart\include
+\to \everyFLOWchart
+
+\unexpanded\def\FLOW_name #name{\ctxcommand{flow_set_name("#name")}\ignorespaces}
+\unexpanded\def\FLOW_shape #shape{\ctxcommand{flow_set_shape("#shape")}\ignorespaces}
+\unexpanded\def\FLOW_destination#destination{\ctxcommand{flow_set_destination("#destination")}\ignorespaces}
+\unexpanded\def\FLOW_focus #focus{\ctxcommand{flow_set_focus("#focus")}\ignorespaces}
+\unexpanded\def\FLOW_overlay #overlay{\ctxcommand{flow_set_overlay("#overlay")}\ignorespaces}
+\unexpanded\def\FLOW_location #location{\ctxcommand{flow_set_location("#location")}\ignorespaces}
+\unexpanded\def\FLOW_figure #figure{\ctxcommand{flow_set_figure("#figure")}\ignorespaces}
+
+\unexpanded\def\FLOW_text {\dosingleempty\module_charts_FLOW_text}
+\unexpanded\def\FLOW_label {\dosingleempty\module_charts_FLOW_label}
+\unexpanded\def\FLOW_comment {\dosingleempty\module_charts_FLOW_comment}
+\unexpanded\def\FLOW_exit {\dosingleempty\module_charts_FLOW_exit}
+\unexpanded\def\FLOW_connection{\dodoubleempty\module_charts_FLOW_connection}
+\unexpanded\def\FLOW_include {\dodoubleempty\module_charts_FLOW_include}
+
+\unexpanded\def\module_charts_FLOW_text [#align]#text{\ctxcommand{flow_set_text("#align",\!!bs\detokenize{#text}\!!es)}\ignorespaces}
+\unexpanded\def\module_charts_FLOW_label [#location]#text{\ctxcommand{flow_set_label("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces}
+\unexpanded\def\module_charts_FLOW_comment [#location]#text{\ctxcommand{flow_set_comment("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces}
+\unexpanded\def\module_charts_FLOW_exit [#location]#text{\ctxcommand{flow_set_exit("#location",\!!bs\detokenize{#text}\!!es)}\ignorespaces}
+\unexpanded\def\module_charts_FLOW_connection[#location][#offset]#name{\ctxcommand{flow_set_connection("#location","#offset","#name")}\ignorespaces}
+
+\unexpanded\def\module_charts_FLOW_include [#name][#settings]{%
+ \begingroup
+ \getparameters[FLOWi][x=1,y=1,#settings]%
+ \ctxcommand{flow_set_include("#name",\number\FLOWix,\number\FLOWiy,\!!bs\detokenize{#settings}\!!es)}%
+ \endgroup
+ \ignorespaces
+}
+
+\setvariables
+ [flowcell:text]
+ [x=1,
+ y=1,
+ text=,
+ align=,
+ set=\setups{flowcell:text:place}]
+
+\def\FLOWx{\getvariable{flowcell:text}{x}} % compatibility (for Willi)
+\def\FLOWy{\getvariable{flowcell:text}{y}} % compatibility (for Willi)
+
+% \c!background={\@@FLOWbackground,\FLOWoverlay},
+
+\defineoverlay
+ [flowcell:figure]
+ [\overlayfigure{\getvariable{flowcell:text}{figure}}]
+
+\startsetups flowcell:text:place
+ \begingroup
+ \iftrialtypesetting
+ \directsetup{flowcell:text:place:indeed}
+ \else \iflocation
+ \doifelsenothing {\getvariable{flowcell:text}{destination}} {
+ \directsetup{flowcell:text:place:indeed}
+ } {
+ % tricky: scaling and moving around is not taken into account
+ \setupinteraction[\c!color=,\c!contrastcolor=]
+ \gotobox{\directsetup{flowcell:text:place:indeed}}[\getvariable{flowcell:text}{destination}]
+ }
+ \else
+ \directsetup{flowcell:text:place:indeed}
+ \fi \fi
+ \endgroup
+\stopsetups
+
+\startsetups flowcell:text:place:indeed
+ \begingroup
+ \directsetup{flowcell:text:user}
+ \doifelsenothing {\getvariable{flowcell:text}{figure}} {
+ \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty
+ {\getvariable{flowcell:text}{text}}
+ } {
+ \expandcheckedcsname{flowcell:}{\getvariable{flowcell:text}{align}}\empty
+ [\c!background=flowcell:figure]
+ {\getvariable{flowcell:text}{text}}
+ }
+ \endgroup
+\stopsetups
+
+\defineframed % to be discussed: shape or global
+ [flowcell:base]
+ [\c!offset=\v!overlay, % no strut ?
+ \c!frame=\FLOWchartparameter\c!frame,
+ \c!background=\FLOWchartparameter\c!background,
+ \c!backgroundcolor=\FLOWchartparameter\c!backgroundcolor,
+ %\c!foregroundcolor=\FLOWshapeparameter\c!foregroundcolor,
+ \c!align=\v!middle,
+ \c!bottom=\vfill,
+ \c!top=\vfill,
+ \c!width=\FLOWchartparameter\c!width,
+ \c!height=\FLOWchartparameter\c!height,
+ % \c!rulethickness=\FLOWchartparameter\c!rulethickness,
+ \c!rulethickness=\zeropoint, % comment for tracing
+ \c!framecolor=\FLOWchartparameter\c!framecolor]
+
+\defineframed[flowcell:] [flowcell:base]
+\defineframed[flowcell:l] [flowcell:base][\c!align=\v!flushleft]
+\defineframed[flowcell:r] [flowcell:base][\c!align=\v!flushright]
+\defineframed[flowcell:m] [flowcell:base][\c!align=\v!middle]
+\defineframed[flowcell:c] [flowcell:base][\c!align=\v!middle]
+
+\defineframed[flowcell:t] [flowcell:base][\c!top=]
+\defineframed[flowcell:b] [flowcell:base][\c!bottom=]
+
+\defineframed[flowcell:lt][flowcell:base][\c!top=,\c!align=\v!flushleft]
+\defineframed[flowcell:rt][flowcell:base][\c!top=,\c!align=\v!flushright]
+\defineframed[flowcell:mt][flowcell:base][\c!top=,\c!align=\v!middle]
+\defineframed[flowcell:ct][flowcell:base][\c!top=,\c!align=\v!middle]
+
+\defineframed[flowcell:lb][flowcell:base][\c!bottom=,\c!align=\v!flushleft]
+\defineframed[flowcell:rb][flowcell:base][\c!bottom=,\c!align=\v!flushright]
+\defineframed[flowcell:mb][flowcell:base][\c!bottom=,\c!align=\v!middle]
+\defineframed[flowcell:cb][flowcell:base][\c!bottom=,\c!align=\v!middle]
+
+% \startsetups flowcell:text:user
+% \setupframed
+% [flowcell:base]
+% [background=flowcell]
+% \definelayer
+% [flowcell]
+% [width=\namedframedparameter{flowcell:base}{width},
+% height=\namedframedparameter{flowcell:base}{height}]
+% \setlayerframed
+% [flowcell]
+% [preset=rightbottom,offset=-2.75ex]
+% [frame=off]
+% {\tx\FLOWx.\FLOWy}
+% \stopsetups
+%
+% % or:
+%
+% \setupframed
+% [flowcell:base]
+% [background={flowcell-1,flowcell-2}]
+%
+% \defineoverlay
+% [flowcell-1]
+% [\directsetup{flowcell-1}]
+%
+% \definelayer
+% [flowcell-2]
+% [width=\overlaywidth,
+% height=\overlayheight]
+%
+% \startsetups flowcell-1
+% \setlayerframed
+% [flowcell-2]
+% [preset=rightbottom,offset=-2.75ex]
+% [frame=off]
+% {\tx\FLOWx.\FLOWy}
+% \stopsetups
+
+% %D \starttyping
+% %D \setupFLOWsplit
+% %D [nx=5,ny=10,
+% %D dx=0,dy=0,
+% %D before=,
+% %D after=\page]
+% %D
+% %D \FLOWcharts[mybigflow]
+% %D \stoptyping
+% %D
+% %D \starttyping
+% %D \splitfloat
+% %D {\placefigure{What a big flowchart this is!}}
+% %D {\FLOWcharts[mybigflow]}
+% %D \stoptyping
+
+% \setupFLOWsplit
+% [nx=5,
+% ny=8,
+% dx=1,
+% dy=1,
+% command=\framed,
+% before=\page,
+% after=\page]
+%
+% \FLOWchart[demo] \page
+% \FLOWchart[demo][split=yes] \page
+% \FLOWchart[demo][x=1,y=1,nx=5,ny=8] \page
+% \FLOWchart[demo][x=1,y=9,nx=5,ny=10] \page
+
+\protect
+
+\continueifinputfile{m-chart.mkvi}
+
+\input chrt-xml.tex
+
+\usemodule[abr-01]
+
+\setupFLOWcharts[option=test]
+\setupFLOWcharts[frame=on]
+\setupinteraction[state=start]
+
+% \setupFLOWcharts[dx=30pt,dy=30pt]
+
+\startMPinclusions
+ predefined_shapes[101] := fullcircle ;
+\stopMPinclusions
+
+\startFLOWchart[demo]
+ \startFLOWcell[framecolor=darkgray]
+ \name {start}
+ \location {1,1}
+ \shape {action}
+ \text {start}
+ \connection [bl] {one}
+ \stopFLOWcell
+ \startFLOWcell[framecolor=darkred]
+ \name {one}
+% \destination{CloseDocument}
+ \location {2,2}
+% \shape {action}
+ \shape {101}
+ \text {first}
+% \label [b] {\bfx bottom}
+ \connection [rt] {two}
+% \exit [l] {exit l}
+% \exit [r] {exit r}
+% \exit [t] {exit t}
+% \exit [b] {exit b}
+ \stopFLOWcell
+ \setupFLOWshapes[framecolor=darkgray]
+ \startFLOWcell % [foregroundcolor=white]
+ \name {two}
+% \destination{CloseDocument}
+ \location {3,3}
+ \shape {action}
+ \text {second}
+ \figure {cow.pdf}
+% \label [l] {\bfx left}
+% \exit [l] {exit l}
+% \exit [r] {exit r}
+% \exit [t] {exit t}
+% \exit [b] {exit b}
+ \stopFLOWcell
+\stopFLOWchart
+
+\starttext
+
+\startTEXpage
+% \FLOWchart[convert-en]
+% \FLOWchart[conversion 1]
+% \FLOWchart[conversion 7]
+% \FLOWchart[conversion 9]
+% \FLOWchart[conversion 10]
+ \FLOWchart[demo]
+
+\stopTEXpage
+
+\startTEXpage
+ \FLOWchart[conversion 10]
+\stopTEXpage
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-chemic.mkiv b/tex/context/modules/mkiv/m-chemic.mkiv
new file mode 100644
index 000000000..1dd403fae
--- /dev/null
+++ b/tex/context/modules/mkiv/m-chemic.mkiv
@@ -0,0 +1,20 @@
+%D \module
+%D [ file=ppchtex (m-chemic),
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten},
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{ppchtex}{not loaded as support for chemistry in now built in}
+
+% \usemodule[pictex] % we will get rid of this
+% \input ppchtex.mkiv \relax
+
+\endinput
diff --git a/tex/context/modules/mkiv/m-cweb.mkiv b/tex/context/modules/mkiv/m-cweb.mkiv
new file mode 100644
index 000000000..2546b2342
--- /dev/null
+++ b/tex/context/modules/mkiv/m-cweb.mkiv
@@ -0,0 +1,1373 @@
+%D \module
+%D [ file=m-cweb,
+%D version=1997.01.15,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\CWEB\ Pretty Printing Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module has to be redone in the mkiv way.
+
+%D First some auxiliary stuff, to be moved to system module.
+
+\def\dodofindfirstcharacter#1%
+ {\ifx#1\relax
+ \let\next=\egroup
+ \else
+ \handlecase
+ {\expandafter\ifnum\expandafter\catcode\expandafter`#1=11
+ \def\next##1\relax{\egroup\def\firstcharacter{#1}}%
+ \fi}%
+ \fi
+ \next}
+
+\def\dofindfirstcharacter#1#2%
+ {\def\firstcharacter{}%
+ \bgroup
+ \defconvertedargument\ascii{#2}%
+ \let\next\dodofindfirstcharacter
+ \let\handlecase#1%
+ \expandafter\next\ascii\relax}
+
+\def\normalcase#1%
+ {#1}
+
+\def\findfirstcharacter%
+ {\dofindfirstcharacter\lowercase}
+
+\def\FindFirstCharacter%
+ {\dofindfirstcharacter\normalcase}
+
+\def\FINDFIRSTCHARACTER%
+ {\dofindfirstcharacter\uppercase}
+
+% nog doen:
+%
+% \deactivateCWEB in output routine
+% status info
+% gelinkte entries
+% parskip en parindent
+
+%D \gdef\CWEBquote#1.{{\em Quote :}\ #1.} % checks the .
+
+%D This module (re)implements the \CWEB\ macros as defined in
+%D the file \type{cwebmac.tex}.
+%D
+%D \CWEB\ uses short, often one character long, names for
+%D macros. This is no real problem because no one is supposed
+%D to read and understand the files generated by \CWEB. The
+%D standard macros are meant for \PLAIN\ \TEX\ users. In
+%D \CONTEXT\ and other macro packages however, there is a
+%D potential conflict with format specific or user defined
+%D commands. Furthermore, the \CWEB\ macros implement their own
+%D output routines. When integrating \CWEB\ documents in
+%D another environment, the \CWEB\ specific macros have to be
+%D made local. The first part of this module is dedicated to
+%D this feature.
+%D
+%D Instead of using \type{\def} and \type{\let} for defining
+%D macros, we use:
+%D
+%D \starttyping
+%D \defCEBmacro arguments {meaning}
+%D \letCEBmacro arguments {meaning}
+%D \stoptyping
+%D
+%D \CWEB files contain implicit calls to macros that generate
+%D the table of contents, the lists of sections and the index.
+%D Because we want to be much more flexible, we implemented our
+%D own alternatives, and therefore have to bypass the original
+%D ones. The next macro is used for defining these obsolete
+%D \CWEB\ macros. The dummies take care of arguments.
+%D
+%D \starttyping
+%D \defCEBdummy arguments {meaning}
+%D \stoptyping
+%D
+%D The list of \CWEB\ specific macro names is saved in a
+%D \TOKENLIST. This serves two purposes. First it enables us to
+%D activate the \CWEB\ macros, which are saved under a
+%D different name, second it can be used to temporary restore
+%D the meanings, for instance when the output routine builds
+%D the page.
+
+\newtoks\CWEBmacros
+
+%D Activating and deactivating is done by means of:
+%D
+%D \starttyping
+%D \activateCWEB
+%D \deactivateCWEB
+%D \stoptyping
+%D
+%D Which are implemented as:
+
+\def\activateCWEB%
+ {\let\doCWEB=\activateCWEBmacro
+ \the\CWEBmacros}
+
+\def\deactivateCWEB%
+ {\let\doCWEB=\deactivateCWEBmacro
+ \the\CWEBmacros}
+
+%D The three definition macros append the name of the macro to
+%D the list. The first two macros save the meaning, the last one
+%D assigns \type{{}} to the macro and gobbles original meaning.
+
+\long\def\defCWEBmacro#1%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \setvalue{newCWEB\string#1}}
+
+\long\def\letCWEBmacro#1%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \letvalue{newCWEB\string#1}}
+
+\long\def\defCWEBdummy#1#2#%
+ {\appendtoks\doCWEB#1\to\CWEBmacros
+ \setvalue{newCWEB\string#1}#2{}%
+ \gobbleoneargument}
+
+%D The macro \type{\defCWEBdummy} of course takes care of the
+%D argument. This leaves the two (de|)|activating macros:
+
+\def\CWEBmacro#1%
+ {\getvalue{newCWEB\string#1}}
+
+\def\activateCWEBmacro#1%
+ {\letvalue{oldCWEB\string#1}=#1%
+ \def#1{\CWEBmacro#1}}
+
+\def\deactivateCWEBmacro#1%
+ {\expandafter\let\expandafter#1\expandafter=\csname oldCWEB\string#1\endcsname}
+
+%D I did consider loading the \CWEB\ macros using temporary
+%D substitutes of \type{\def}, \type{\font}, \type{\newbox} etc.
+%D The main problem is that the file contains more than
+%D definitions and taking all kind of assignments into account
+%D too would not make things easier. So I decided to stick to
+%D the method as just described.
+
+%D Now we're ready for the real job. What follows is a partial
+%D adaption of the file \type{cwebmac.tex}, version 3.1, dated
+%D September 1994 and written by Levy and Knuth. When possible
+%D we kept the original meaning, but we've granted ourselves
+%D the freedom to reformat the macro's for readibility.
+%D
+%D We'll only present the macros we actually use. The source
+%D however contains the original implementation.
+
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 3.1 --- September 1994.
+%
+% \ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros
+%
+% \xdef\fmtversion{\fmtversion+CWEB3.1}
+
+%D \macros{.}{}
+%D
+%D \CWEBquote preserve a way to get the dot accent (all
+%D other accents will still work as usual).
+
+\letCWEBmacro\: = \.
+
+% \parskip = 0pt % no stretch between paragraphs
+% \parindent = 1em % for paragraphs and for the first line of C text
+
+% \font\ninerm = cmr9
+% \let\mc = \ninerm % medium caps
+% \font\eightrm = cmr8
+% \let\sc = \eightrm % small caps (NOT a caps-and-small-caps font)
+% \let\mainfont = \tenrm
+% \let\cmntfont = \tenrm
+% \font\tenss = cmss10
+% \let\cmntfont = \tenss % alternative comment font
+% \font\titlefont = cmr7 scaled \magstep4 % title on the contents page
+% \font\ttitlefont = cmtt10 scaled \magstep2 % typewriter type in title
+% \font\tentex = cmtex10 % TeX extended character set (used in strings)
+% \fontextraspace\tentex = 0pt % no double space after sentences
+
+%D \macros{mc,sc,cmntfont,eightrm}{}
+%D
+%D The naming of the fonts in in line with those in \PLAIN\
+%D \TEX. Although \CONTEXT\ implements its own scheme, there is
+%D still support for the \PLAIN\ ones. We keep the original
+%D names, but change their meaning. That way the macros obey
+%D switching to other sizes or styles.
+
+\defCWEBmacro\mc {\tx}
+\defCWEBmacro\sc {\txx}
+\defCWEBmacro\cmntfont {\ss}
+\defCWEBmacro\eightrm {\tx}
+
+%D \macros{tentex,sevenrm,sevensy,teni}{}
+%D
+%D The next one uses a temporary solution. The \type{cmtex10}
+%D font is not part of the default mechanism. We make use of
+%D the \CONTEXT\ variables \type{\textface}, \type{\scriptface}
+%D and \type{\scriptscriptface}, which hold the current
+%D sizes.
+
+\defCWEBmacro\tentex%
+ {\font\next=cmtex10 at \textface
+ \fontextraspace\next\zeropoint
+ \next}
+
+\defCWEBmacro\sevenrm {\getvalue{\scriptface rmtf}}
+\defCWEBmacro\sevensy {\getvalue{\scriptface mmsy}}
+\defCWEBmacro\teni {\getvalue{\textface mmmi}}
+
+%D \macros{CWEBpt}{}
+%D
+%D The original macros are based on a 10~point bodyfont size. We
+%D therefore have to specify dimension in points a bit
+%D different. Specifications like .6pt are changed to
+%D \type{.06} times \type{\bodyfontsize}.
+
+\defCWEBmacro\CWEBpt {\bodyfontsize} % still dutch
+
+%D \macros{CEE,UNIX,TEX,CPLUSPLUS}{}
+%D
+%D Next come some logo's. It does not make much sense to use
+%D the \CONTEXT\ logo mechanism here, so we simply say:
+
+\defCWEBmacro \CEE/{{\mc C\spacefactor1000}}
+\defCWEBmacro \UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\defCWEBmacro \TEX/{\TeX}
+\defCWEBmacro\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\defCWEBmacro \Cee{\CEE/} % for backward compatibility
+
+%D \macros{\ }{}
+%D
+%D Now we come to the real work: the short commands that make
+%D up the typography.
+%D
+%D \CWEBquote italic type for identifiers.
+
+\defCWEBmacro\\#1%
+ {\leavevmode\hbox{\it#1\/\kern.05em}}
+
+%D \macros{\string|}{}
+%D
+%D \CWEBquote one letter identifiers look better this way.
+
+\defCWEBmacro\|#1%
+ {\leavevmode\hbox{$#1$}}
+
+%D \macros{\string\&}{}
+%D
+%D \CWEBquote boldface type for reserved words.
+
+\defCWEBmacro\&#1%
+ {\leavevmode
+ \hbox
+ {\def\_%
+ {\kern.04em
+ \vbox{\hrule width.3em height .06\CWEBpt}% .6pt}%
+ \kern.08em}%
+ \bf#1\/\kern.05em}}
+
+%D \macros{.}{}
+%D
+%D Here we use the previously saved period. This macro
+%D takes care of special characters in strings.
+
+\defCWEBmacro\.#1%
+ {\leavevmode
+ \hbox
+ {\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+
+%D \macros{)}{}
+%D
+%D Some discretionary hack.
+
+\defCWEBmacro\)%
+ {\discretionary{\hbox{\tentex\BS}}{}{}}
+
+%D \macros{AT}{}
+%D
+%D \CWEBquote at sign for control text (not needed in versions
+%D $>=$ 2.9).
+
+\defCWEBmacro\AT{@}
+
+%D \macros{ATL,postATL,NOATL}{}
+%D
+%D A two step macro that handles whatever.
+
+\defCWEBmacro\ATL%
+ {\par
+ \noindent
+ \bgroup
+ \catcode`\_=12
+ \postATL}
+
+\defCWEBmacro\postATL#1 #2 %
+ {\bf letter \\{\uppercase{\char"#1}} tangles as \tentex "#2"%
+ \egroup
+ \par}
+
+\defCWEBmacro\noATL#1 #2 %
+ {}
+
+%D \macros{noatl}{}
+%D
+%D \CWEBquote suppress output from \type{@l}.
+
+\defCWEBmacro\noatl%
+ {\let\ATL=\noATL}
+
+% \defCWEBmacro\ATH%
+% {\X\kern-.5em:Preprocessor definitions\X}
+
+%D \macros{PB}
+%D
+%D \CWEBquote hook for program brackets {\tttf\string|...\string|}
+%D in TeX part or section name.
+
+\defCWEBmacro\PB%
+ {\relax}
+
+% \chardef\AM = `\& % ampersand character in a string
+% \chardef\BS = `\\ % backslash in a string
+% \chardef\LB = `\{ % left brace in a string
+% \chardef\RB = `\} % right brace in a string
+% \chardef\TL = `\~ % tilde in a string
+% \chardef\UL = `\_ % underline character in a string
+% \chardef\CF = `\^ % circumflex character in a string
+
+\defCWEBmacro\AM {\char`\&} % ampersand character in a string
+\defCWEBmacro\BS {\char`\\} % backslash in a string
+\defCWEBmacro\LB {\char`\{} % left brace in a string
+\defCWEBmacro\RB {\char`\}} % right brace in a string
+\defCWEBmacro\TL {\char`\~} % tilde in a string
+\defCWEBmacro\UL {\char`\_} % underline character in a string
+\defCWEBmacro\CF {\char`\^} % circumflex character in a string
+
+\defCWEBmacro\SP {{\tt\char`\ }} % (visible) space in a string
+
+% \newbox\PPbox \setbox\PPbox=\hbox
+% {\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+% \newbox\MMbox \setbox\MMbox=\hbox
+% {\kern.5pt\raise1pt\hbox{\sevensy\char0\kern-1pt\char0}\kern.5pt}
+% \newbox\MGbox \setbox\MGbox=\hbox % symbol for ->
+% {\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+% \newbox\MODbox \setbox\MODbox=\hbox
+% {\eightrm\%}
+%
+% \def\PP {\copy\PPbox}
+% \def\MM {\copy\MMbox}
+% \def\MG {\copy\MGbox}
+% \def\MOD {\mathbin{\copy\MODbox}}
+
+\defCWEBmacro\PP% symbol for ++
+ {\kern.05\CWEBpt
+ \raise.1\CWEBpt\hbox{\sevenrm+\kern-.1\CWEBpt+}%
+ \kern.05\CWEBpt}
+
+\defCWEBmacro\MM%
+ {\kern.05\CWEBpt
+ \raise.1\CWEBpt\hbox{\sevensy\char0\kern-.1\CWEBpt\char0}%
+ \kern.05\CWEBpt}
+
+\defCWEBmacro\MG%
+ {\kern-.2\CWEBpt
+ \lower.3\CWEBpt\hbox{\teni\char'176}%
+ \kern .1\CWEBpt}
+
+\defCWEBmacro\MRL#1%
+ {\mathrel{\let\K==#1}}
+
+% \def\MRL#1%
+% {\KK#1}
+% \def\KK#1#2%
+% {\buildrel\;#1\over{#2}}
+
+\letCWEBmacro\GG = \gg
+\letCWEBmacro\LL = \ll
+\letCWEBmacro\NULL = \Lambda
+
+% \mathchardef\AND = "2026 % bitwise and; also \& (unary operator)
+
+\defCWEBmacro\AND% redefines itself (funny)
+ {\mathchardef\AND="2026 \AND} % bitwise and; also \& (unary operator)
+
+\letCWEBmacro\OR = \mid % bitwise or
+\letCWEBmacro\XOR = \oplus % bitwise exclusive or
+\defCWEBmacro\CM {{\sim}} % bitwise complement
+\defCWEBmacro\MOD {\mathbin{\eightrm\%}}
+\defCWEBmacro\DC {\kern.1em{::}\kern.1em} % symbol for ::
+\defCWEBmacro\PA {\mathbin{.*}} % symbol for .*
+\defCWEBmacro\MGA {\mathbin{\MG*}} % symbol for ->*
+\defCWEBmacro\this {\&{this}}
+
+% \newbox \bak % backspace one em
+% \newbox \bakk % backspace two ems
+%
+% \setbox\bak =\hbox to -1em{}
+% \setbox\bakk=\hbox to -2em{}
+
+\newcount\CWEBind % current indentation in ems
+
+\defCWEBmacro\1% indent one more notch
+ {\global\advance\CWEBind by 1
+ \hangindent\CWEBind em}
+
+\defCWEBmacro\2% indent one less notch
+ {\global\advance\CWEBind by -1 }
+
+\defCWEBmacro\3#1% optional break within a statement
+ {\hfil
+ \penalty#10
+ \hfilneg}
+
+\defCWEBmacro\4% backspace one notch
+ {\hbox to -1em{}}
+
+\defCWEBmacro\5% optional break
+ {\hfil
+ \penalty-1
+ \hfilneg
+ \kern2.5em
+ \hbox to -2em{}%
+ \ignorespaces}
+
+\defCWEBmacro\6% forced break
+ {\ifmmode
+ \else
+ \par
+ \hangindent\CWEBind em
+ \noindent
+ \kern\CWEBind em
+ \hbox to -2em{}%
+ \ignorespaces
+ \fi}
+
+\defCWEBmacro\7% forced break and a little extra space
+ {\Y
+ \6}
+
+\defCWEBmacro\8% no indentation
+ {\hskip-\CWEBind em
+ \hskip 2em}
+
+\defCWEBmacro\9#1%
+ {}
+
+\newcount\gdepth % depth of current major group, plus one
+\newcount\secpagedepth
+\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1
+
+% \newtoks\gtitle % title of current major group
+% \newskip\intersecskip
+% \intersecskip=12pt minus 3pt % space between sections
+
+% \let\yskip=\smallskip
+
+\defCWEBmacro\?%
+ {\mathrel?}
+
+% \def\note#1#2.%
+% {\Y\noindent
+% {\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}}
+
+\defCWEBmacro\lapstar%
+ {\rlap{*}}
+
+% \def\stsec%
+% {\rightskip=0pt % get out of C mode (cf. \B)
+% \sfcode`;=1500
+% \pretolerance 200
+% \hyphenpenalty 50
+% \exhyphenpenalty 50
+% \noindent{\let\*=\lapstar\bf\secstar.\quad}}
+%
+% \let\startsection=\stsec
+
+\defCWEBmacro\defin#1%
+ {\global\advance\CWEBind by 2 \1\&{#1 } } % begin `define' or `format'
+
+% \def\A% xref for doubly defined section name
+% {\note{See also section}}
+%
+% \def\As% xref for multiply defined section name
+% {\note{See also sections}}
+
+\defCWEBmacro\B%
+ {\rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\CWEBind=2 \1\ \unskip}
+
+\defCWEBmacro\C#1%
+ {\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+
+% \let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+
+\defCWEBmacro\SHC#1%
+ {\5\5\quad$//\,${\cmntfont#1}}
+
+% \def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+% \def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+
+\defCWEBmacro\D% macro definition
+ {\defin{\#define}}
+
+\letCWEBmacro\E=\equiv % equivalence sign
+
+% \def\ET% conjunction between two section numbers
+% { and~}
+%
+% \def\ETs% conjunction between the last two of several section numbers
+% {, and~}
+
+\defCWEBmacro\F% format definition
+ {\defin{format}}
+
+\letCWEBmacro\G = \ge % greater than or equal sign
+
+% \H is long Hungarian umlaut accent
+
+\letCWEBmacro\I = \ne % unequal sign
+
+\defCWEBmacro\J% TANGLE's join operation
+ {\.{@\&}}
+
+% \let\K== % assignment operator
+
+\letCWEBmacro\K = \leftarrow % "honest" alternative to standard assignment operator
+
+% \L is Polish letter suppressed-L
+
+% \outer\def\M#1%
+% {\MN{#1}%
+% \ifon
+% \vfil
+% \penalty-100
+% \vfilneg % beginning of section
+% \vskip\intersecskip
+% \startsection
+% \ignorespaces}
+%
+% \outer\def\N#1#2#3.%
+% {\gdepth=#1%
+% \gtitle={#3}%
+% \MN{#2}% beginning of starred section
+% \ifon
+% \ifnum#1<\secpagedepth
+% \vfil
+% \eject % force page break if depth is small
+% \else
+% \vfil
+% \penalty-100
+% \vfilneg
+% \vskip\intersecskip
+% \fi
+% \fi
+% \message{*\secno}% progress report
+% \edef\next%
+% {\write\cont % write to contents file
+% {\ZZ{#3}{#1}{\secno}{\noexpand\the\pageno}}}%
+% \next % \ZZ{title}{depth}{sec}{page}
+% \ifon
+% \startsection
+% {\bf#3.\quad}%
+% \ignorespaces}
+%
+% \def\MN#1%
+% {\par % common code for \M, \N
+% {\xdef\secstar{#1}%
+% \let\*=\empty
+% \xdef\secno{#1}}% remove \* from section name
+% \ifx\secno\secstar
+% \onmaybe
+% \else
+% \ontrue
+% \fi
+% \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}}
+%
+% each \mark is {section reference or null}{depth plus 1}{group title}
+
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+
+\defCWEBmacro\Q {\note{This code is cited in section}} % xref for mention of a section
+\defCWEBmacro\Qs {\note{This code is cited in sections}} % xref for mentions of a section
+
+% \S is section sign
+
+\defCWEBmacro\T#1%
+ {\leavevmode % octal, hex or decimal constant
+ \hbox
+ {$\def\?{\kern.2em}%
+ \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct
+ \let\^=\hex
+ {#1}$}}
+
+\defCWEBmacro\U {\note{This code is used in section}} % xref for use of a section
+\defCWEBmacro\Us {\note{This code is used in sections}} % xref for uses of a section
+
+\letCWEBmacro\R = \lnot % logical not
+\letCWEBmacro\V = \lor % logical or
+\letCWEBmacro\W = \land % logical and
+
+% defined later on
+%
+% \def\X#1:#2\X%
+% {\ifmmode
+% \gdef\XX{\null$\null}%
+% \else
+% \gdef\XX{}%
+% \fi % section name
+% \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX}
+
+\unprotect
+
+\def\theCWEByskip {\blank[\v!small]}
+\def\theCWEBvskip {\blank[\v!big]}
+
+\protect
+
+\defCWEBmacro\Y%
+ {\par
+ \yskip}
+
+\defCWEBmacro\yskip%
+ {\theCWEByskip}
+
+\letCWEBmacro\Z = \le
+% \letCWEBmacro\ZZ = \let % now you can \write the control sequence \ZZ
+\letCWEBmacro\* = *
+
+\defCWEBmacro\oct%
+ {\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}
+
+\defCWEBmacro\hex%
+ {\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}}
+
+\defCWEBmacro\vb#1%
+ {\leavevmode
+ \hbox
+ {\kern.2\CWEBpt
+ \vrule
+ \vtop
+ {\vbox
+ {\hrule
+ \hbox{\strut\kern.2\CWEBpt\.{#1}\kern.2\CWEBpt}}
+ \hrule}%
+ \vrule
+ \kern.2\CWEBpt}} % verbatim string
+
+\def\onmaybe%
+ {\let\ifon=\maybe}
+
+\let\maybe=\iftrue
+
+\newif\ifon
+
+% \newif\iftitle
+% \newif\ifpagesaved
+%
+% \def\lheader%
+% {\mainfont
+% \the\pageno
+% \eightrm
+% \qquad
+% \grouptitle
+% \hfill
+% \title
+% \qquad
+% \mainfont
+% \topsecno} % top line on left-hand pages
+%
+% \def\rheader%
+% {\mainfont
+% \topsecno
+% \eightrm
+% \qquad
+% \title
+% \hfill
+% \grouptitle
+% \qquad
+% \mainfont
+% \the\pageno} % top line on right-hand pages
+%
+% \def\grouptitle
+% {\let\i=I
+% \let\j=J
+% \uppercase\expandafter{\expandafter\takethree\topmark}}
+%
+% \def\topsecno%
+% {\expandafter\takeone\topmark}
+%
+% \def\takeone #1#2#3{#1}
+% \def\taketwo #1#2#3{#2}
+% \def\takethree #1#2#3{#3}
+%
+% \def\nullsec%
+% {\eightrm
+% \kern-2em} % the \kern-2em cancels \qquad in headers
+%
+% \let\page=\pagebody % \def\page {\box255 }
+% \raggedbottom % \normalbottom % faster, but loses plain TeX footnotes
+%
+% \def\normaloutput#1#2#3%
+% {\shipout\vbox
+% {\ifodd
+% \pageno
+% \hoffset=\pageshift
+% \fi
+% \vbox to \fullpageheight
+% {\iftitle
+% \global\titlefalse
+% \else
+% \hbox to \pagewidth
+% {\vbox to 10pt{}%
+% \ifodd\pageno #3\else#2\fi}
+% \fi
+% \vfill#1}} % parameter #1 is the page itself
+% \global\advance\pageno by 1}
+%
+% \gtitle={\.{CWEB} output} % this running head is reset by starred sections
+%
+% \mark{\noexpand\nullsec0{\the\gtitle}}
+%
+% \def\title%
+% {\expandafter\uppercase\expandafter{\jobname}}
+%
+% \def\topofcontents%
+% {\centerline{\titlefont\title}
+% \vskip.7in
+% \vfill} % this material will start the table of contents page
+
+\def\botofcontents%
+ {\vfill
+ \centerline{\covernote}} % this material will end the table of contents page
+
+\def\covernote%
+ {}
+
+% some leftover
+
+\defCWEBmacro\contentspagenumber{0} % default page number for table of contents
+
+% \newdimen\pagewidth \pagewidth = 158mm % the width of each page
+% \newdimen\pageheight \pageheight = 223mm % the height of each page
+% \newdimen\fullpageheight \fullpageheight = 240mm % page height including headlines
+% \newdimen\pageshift \pageshift = 0in % shift righthand pages wrt lefthand ones
+%
+% \def\magnify#1%
+% {\mag=#1
+% \pagewidth=6.5truein
+% \pageheight=8.7truein
+% \fullpageheight=9truein
+% \setpage}
+%
+% \def\setpage%
+% {\hsize\pagewidth
+% \vsize\pageheight} % use after changing page size
+%
+% \def\contentsfile {\jobname.toc} % file that gets table of contents info
+% \def\readcontents {\input \contentsfile}
+% \def\readindex {\input \jobname.idx}
+% \def\readsections {\input \jobname.scn}
+%
+% \newwrite\cont
+% \output{\setbox0=\page % the first page is garbage
+% \openout\cont=\contentsfile
+% \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+% \global\output{\normaloutput\page\lheader\rheader}}
+% \setpage
+% \vbox to \vsize{} % the first \topmark won't be null
+
+\defCWEBdummy\magnify#1% magnify the page
+ {}
+
+\defCWEBmacro\ch%
+ {\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+
+% \newbox\sbox % saved box preceding the index
+% \newbox\lbox % lefthand column in the index
+%
+% \def\inx%
+% {\par\vskip6pt plus 1fil % we are beginning the index
+% \def\page{\box255 }
+% \normalbottom
+% \write\cont{} % ensure that the contents file isn't empty
+% \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+% \closeout\cont % the contents information has been fully gathered
+% \output
+% {\ifpagesaved
+% \normaloutput{\box\sbox}\lheader\rheader
+% \fi
+% \global\setbox\sbox=\page
+% \global\pagesavedtrue}
+% \pagesavedfalse
+% \eject % eject the page-so-far and predecessors
+% \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+% \vsize=\pageheight
+% \advance\vsize by -\ht\sbox % the remaining height
+% \hsize=.5\pagewidth
+% \advance\hsize by -10pt
+% % column width for the index (20pt between cols)
+% \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+% \def\lr{L} % this tells whether the left or right column is next
+% \output
+% {\if L\lr
+% \global\setbox\lbox=\page
+% \gdef\lr{R}
+% \else
+% \normaloutput
+% {\vbox to\pageheight
+% {\box\sbox
+% \vss
+% \hbox to\pagewidth{\box\lbox\hfil\page}}}
+% \lheader
+% \rheader
+% \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+% \message{Index:}
+% \parskip 0pt plus .5pt
+% \outer\def\I##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+% \def\[##1]{$\underline{##1}$} % underlined index item
+% \rm
+% \rightskip0pt plus 2.5em
+% \tolerance 10000
+% \let\*=\lapstar
+% \hyphenpenalty 10000
+% \parindent0pt
+% \readindex}
+%
+% \def\fin%
+% {\par\vfill\eject % this is done when we are ending the index
+% \ifpagesaved\null\vfill\eject\fi % output a null index column
+% \if L\lr\else\null\vfill\eject\fi % finish the current page
+% \parfillskip 0pt plus 1fil
+% \def\grouptitle{NAMES OF THE SECTIONS}
+% \let\topsecno=\nullsec
+% \message{Section names:}
+% \output={\normaloutput\page\lheader\rheader}
+% \setpage
+% \def\note##1##2.{\quad{\eightrm##1~##2.}}
+% \def\Q{\note{Cited in section}} % crossref for mention of a section
+% \def\Qs{\note{Cited in sections}} % crossref for mentions of a section
+% \def\U{\note{Used in section}} % crossref for use of a section
+% \def\Us{\note{Used in sections}} % crossref for uses of a section
+% \def\I{\par\hangindent 2em}\let\*=*
+% \readsections}
+%
+% \def\con%
+% {\par\vfill\eject % finish the section names
+% %\ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+% \rightskip = 0pt
+% \hyphenpenalty = 50
+% \tolerance = 200
+% \setpage
+% \output={\normaloutput\page\lheader\rheader}
+% \titletrue % prepare to output the table of contents
+% \pageno=\contentspagenumber
+% \def\grouptitle{TABLE OF CONTENTS}
+% \message{Table of contents:}
+% \topofcontents
+% \line{\hfil Section\hbox to3em{\hss Page}}
+% \let\ZZ=\contentsline
+% \readcontents\relax % read the contents info
+% \botofcontents
+% \end} % print the contents page(s) and terminate
+%
+% \def\contentsline#1#2#3#4%
+% {\ifnum#2=0
+% \smallbreak
+% \fi
+% \line{\consetup{#2}#1
+% \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to3em{\hss#4}}}
+%
+
+\defCWEBmacro\consetup#1%
+ {\ifcase#1 \bf % depth -1 (@**)
+ \or % depth 0 (@*)
+ \or \hskip2em % depth 1 (@*1)
+ \or \hskip4em % depth 2 (@*2)
+ \or \hskip6em % depth 3 (@*3)
+ \or \hskip8em % depth 4 (@*4)
+ \or \hskip10em % depth 5 (@*5)
+ \else \hskip12em
+ \fi} % depth 6 or more
+
+\defCWEBdummy \inx {} % index
+\defCWEBdummy \fin {} % finish
+\defCWEBdummy \con {} % table of contents and finish
+
+\defCWEBdummy \noinx {} % no indexes or table of contents
+\defCWEBdummy \nosecs {} % no index of section names or table of contents
+\defCWEBdummy \nocon {} % no table of contents
+
+\defCWEBmacro\,%
+ {\relax
+ \ifmmode
+ \mskip\thinmuskip
+ \else
+ \thinspace
+ \fi}
+
+% \def\noinx%
+% {\let\inx=\end}
+%
+% \def\nosecs%
+% {\let\FIN=\fin
+% \def\fin%
+% {\let\parfillskip=\end
+% \FIN}}
+%
+% \def\nocon%
+% {\let\con=\end}
+%
+% \newcount\twodigits
+%
+% \def\hours%
+% {\twodigits=\time
+% \divide\twodigits by 60
+% \printtwodigits
+% \multiply\twodigits by -60
+% \advance\twodigits by \time
+% :\printtwodigits}
+%
+% \def\gobbleone1{}
+%
+% \def\printtwodigits%
+% {\advance\twodigits by 100
+% \expandafter\gobbleone\number\twodigits
+% \advance\twodigits by -100 }
+%
+% \def\today%
+% {\ifcase\month
+% \or January\or February\or March\or April\or May\or June%
+% \or July\or August\or September\or October\or November\or December%
+% \fi
+% \space
+% \number\day, \number\year}
+%
+% \def\datethis%
+% {\def\startsection%
+% {\leftline{\sc\today\ at \hours}
+% \bigskip
+% \let\startsection=\stsec
+% \stsec}}
+%
+% \def\datecontentspage%
+% {\def\topofcontents%
+% {\leftline{\sc\today\ at \hours}
+% \bigskip
+% \centerline{\titlefont\title}
+% \vfill}}
+
+\defCWEBdummy\datethis {} % say `\datethis' in limbo, to get your listing timestamped before section 1
+\defCWEBdummy\datecontentspage {} % timestamps the contents page
+
+\defCWEBmacro\TeX%
+ {{\ifmmode\it\fi
+ \leavevmode
+ \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+
+% alternative implementation
+
+\newif\ifCWEBnotes
+
+\defCWEBmacro\Q {\CWEBnotesfalse \note{This code is cited in section}} % xref for mention of a section
+\defCWEBmacro\Qs {\CWEBnotestrue \note{This code is cited in sections}} % xref for mentions of a section
+
+\defCWEBmacro\U {\CWEBnotesfalse \note{This code is used in section}} % xref for use of a section
+\defCWEBmacro\Us {\CWEBnotestrue \note{This code is used in sections}} % xref for uses of a section
+
+\defCWEBmacro\A {\CWEBnotesfalse \note{See also section}} % xref for doubly defined section name
+\defCWEBmacro\As {\CWEBnotestrue \note{See also sections}} % xref for multiply defined section name
+
+\defCWEBmacro\ET% conjunction between two section numbers
+ { and~}
+
+\defCWEBmacro\ETs% conjunction between the last two of several section numbers
+ {, and~}
+
+%\def\processCWEBsectionnumbers[#1]%
+% {\bgroup
+% \def\CWEBcomma%
+% {\def\CWEBcomma{, }}%
+% \def\docommand##1%
+% {\bgroup
+% \def\[####1]{####1}%
+% \xdef\CWEBreference{##1}%
+% \egroup
+% \CWEBcomma{\naar{\donottest{##1}}[web:\CWEBreference]}}%
+% \processcommalist[{#1}]\docommand
+% \egroup}
+
+% \def\processCWEBsectionnumbers[#1]%
+% {\bgroup
+% \def\CWEBcomma%
+% {\def\CWEBcomma{, }}%
+% \def\docommand##1%
+% {\bgroup
+% \def\(####1){####1}%
+% \xdef\CWEBreference{##1}%
+% \egroup
+% \CWEBcomma
+% {\localcolortrue\naar{\donottest{##1}}[web:\CWEBreference]}}%
+% \bgroup
+% \def\[##1]{\(##1)}\let\(=\relax\xdef\CWEBreferences{#1}%
+% \egroup
+% \unexpanded\def\(##1){\[##1]}%
+% \processcommacommand[\CWEBreferences]\docommand
+% \egroup}
+
+\def\processCWEBsectionnumbers[#1]%
+ {\bgroup
+ \def\CWEBcomma%
+ {\def\CWEBcomma{, }}%
+ \def\docommand##1%
+ {\bgroup
+ \def\[####1]{####1}%
+ \xdef\CWEBreference{##1}%
+ \egroup
+ \CWEBcomma{\localcolortrue\goto{\donottest{##1}}[web:\CWEBreference]}}%
+ \processlist{(}{)}{,}\docommand(#1)
+ \egroup}
+
+\def\processCWEBsectionnotes%
+ {\catcode`\s=12
+ \doprocessCWEBsectionnotes}
+
+\def\doprocessCWEBsectionnotes#1.%
+ {\ifCWEBnotes
+ \def\next##1\ET##2##3.%
+ {\processCWEBsectionnumbers[##1]%
+ \if##2s%
+ {, and~\goto{##3}[web:##3]}%
+ \else
+ { and~\goto{##2##3}[web:##2##3]}%
+ \fi}%
+ \next#1.%
+ \else
+ \goto{#1}[web:#1]%
+ \fi
+ \afterCWEBnote % inside group!
+ \egroup}
+
+\let\afterCWEBnote=\relax
+
+\defCWEBmacro\note#1%
+ {\bgroup
+ \Y\noindent
+ \def\afterCWEBnote{\par}%
+ \hangindent2em
+ %\baselineskip10pt
+ \eightrm#1~\processCWEBsectionnotes}
+
+\def\oldCWEBmacroX#1:#2\X% original
+ {\ifmmode
+ \gdef\XX{\null$\null}%
+ \else
+ \gdef\XX{}%
+ \fi % section name
+ \XX$\langle\,${#2\eightrm\kern.5em#1}$\,\rangle$\XX}
+
+\defCWEBmacro\ATH%
+ {\oldCWEBmacroX\kern-.5em:Preprocessor definitions\X}
+
+\def\newCWEBmacroX#1:#2\X% original
+ {\ifmmode
+ \gdef\XX{\null$\null}%
+ \else
+ \gdef\XX{}%
+ \fi % section name
+ \XX$\langle\,$%
+ {#2\eightrm\kern.5em\processCWEBsectionnumbers[{#1}]}%
+ $\,\rangle$\XX}
+
+\defCWEBmacro\X#1:#2\X%
+ {\newCWEBmacroX#1:#2\X}
+
+\definemarking[CWEBfilename]
+\definemarking[CWEBsectiontitle]
+\definemarking[CWEBsectionnumber]
+\definemarking[CWEBsectiondepth]
+
+\defCWEBmacro\M#1%
+ {\MN{#1}%
+ \ifon
+ \vfil
+ \penalty-100
+ \vfilneg % beginning of section
+ \theCWEBvskip
+ \startsection
+ \pagereference[web:#1]%
+ \expanded{\marking[CWEBsectionnumber]{\secno}}%
+ \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}%
+ \ignorespaces}
+
+\defCWEBmacro\N#1#2#3.%
+ {\gdepth=#1%
+ \MN{#2}% beginning of starred section
+ \ifon
+ \ifnum#1<\secpagedepth
+ \vfil
+ \eject % force page break if depth is small
+ \else
+ \vfil
+ \penalty-100
+ \vfilneg
+ \theCWEBvskip
+ \fi
+ \fi
+ \message{*\secno}% progress report
+ \makesectionformat % context
+ \defconvertedargument\ascii{#3}%
+ \edef\next%
+ {\write\CWEBcont % write to contents file
+ {\string\ZZ{\ascii}{#1}{\secno}%
+ {\sectionformat::\noexpand\userfolio}{\noexpand\realfolio}}}%
+ \next % \ZZ{title}{depth}{sec}{page}
+ \ifon
+ \startsection
+ \pagereference[web:#2]%
+ \marking[CWEBsectiontitle] {#3}%
+ \expanded{\marking[CWEBsectionnumber]{\secno}}%
+ \expanded{\marking[CWEBsectiondepth]{\the\gdepth}}%
+ {\bf#3.\quad}%
+ \ignorespaces}
+
+\defCWEBmacro\MN#1%
+ {\par % common code for \M, \N
+ {\xdef\secstar{#1}%
+ \let\*=\empty
+ \xdef\secno{#1}}% remove \* from section name
+ \ifx\secno\secstar
+ \onmaybe
+ \else
+ \ontrue
+ \fi}
+
+\newif\iflinktoCWEBfile
+
+\def\setCWEBlinkfile#1%
+ {\linktoCWEBfiletrue
+ \def\otherCWEBfile{#1}}
+
+\unprotect
+
+\def\gotoCWEBsection#1[#2]%
+ {\iflinktoCWEBfile
+ \bgroup
+ \setupinteraction[\c!color=,\c!style=]%
+ \let\savedreferenceprefix=\referenceprefix
+ \localcolortrue
+ \goto{#1}[\otherCWEBfile::\savedreferenceprefix web:#2]%
+ \egroup
+ \else
+ #1%
+ \fi}
+
+\protect
+
+\defCWEBmacro\startsection%
+ {\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500
+ \pretolerance 200
+ \hyphenpenalty 50
+ \exhyphenpenalty 50
+ \noindent
+ \bgroup
+ \let\*=\lapstar
+ \gotoCWEBsection{\bf\secstar.\quad}[\secno]%
+ \egroup}
+
+\def\ignoreCWEBinput%
+ {\let\normalinput=\input
+ \def\input ##1 %
+ {\let\input=\normalinput}}
+
+\def\loadCWEBmacros#1%
+ {\let\oldN=\N
+ \def\N{\bgroup\setbox0=\vbox\bgroup\endinput}%
+ \ignoreCWEBinput
+ \ReadFile{#1.tex}%
+ \egroup\egroup
+ \let\N=\oldN}
+
+\def\resetCWEBcontext%
+ {\catcode`\|=12 % used in context discretionaries
+ \everypar{} % used for context indentation and floats
+ \parskip=0pt % no stretch between cweb paragraphs
+ \parindent=1em} % is related to cweb backspace etc
+
+\newwrite\CWEBcont
+
+\def\processCWEBsource #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \ignoreCWEBinput
+ \immediate\openout\CWEBcont=#1.toc
+ \write\CWEBcont{\noexpand\unprotect}
+ \message{Source:}
+ \marking[CWEBfilename]{#1}
+ \ReadFile{#1.tex}\relax
+ \write\CWEBcont{\noexpand\protect}
+ \closeout\CWEBcont
+ \par
+ \egroup}
+
+\def\resetCWEBindexentry%
+ {\xdef\currentCWEBindexentry{}}
+
+\def\showCWEBindexentry#1% can be redefined
+ {\theCWEBvskip
+ \vskip3\lineheight
+ \goodbreak
+ \vskip-3\lineheight
+ {\pagereference[web:#1]\bf#1}%
+ \theCWEBvskip}
+
+\def\checkCWEBindexentry#1%
+ {\bgroup
+ \def\\##1{##1}% a dummy that also removes the {}
+ \def\|##1{##1}% another dummy
+ \def\.##1{*##1}% and another (the typewriter one)
+ \def\&##1{##1}% and a last one
+ \def\9##1{##1}% hold this one
+ \catcode`*=11
+ \expandafter\def\expandafter\entry\expandafter{#1}%
+ \defconvertedcommand\ascii\entry
+ \expanded{\FINDFIRSTCHARACTER{\ascii}}%
+ \doifnot{\currentCWEBindexentry}{\firstcharacter}
+ {\doifnot{\firstcharacter}{*} % signal for \firstbunch
+ {\global\let\currentCWEBindexentry=\firstcharacter
+ \showCWEBindexentry{\currentCWEBindexentry}}}%
+ \egroup}
+
+\def\theCWEBbeforeindex {\startcolumns}
+\def\theCWEBafterindex {\stopcolumns}
+
+\def\processCWEBindex #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \resetCWEBindexentry
+ \def\I##1, %
+ {\par
+ \checkCWEBindexentry{##1}%
+ \hangindent2em
+ \noindent##1:\kern1em%
+ \def\next####1.%
+ {\processCWEBsectionnumbers[{####1}]}%
+ \next}%
+ \def\[##1]%
+ {$\underline{##1}$}%
+ \let\*=\lapstar
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+% \parskip 0pt plus .5pt
+ \rightskip0pt plus 2.5em
+ \tolerance 10000
+ \hyphenpenalty 10000
+ \parindent0pt
+ \message{Index:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {index}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \theCWEBbeforeindex
+ \ReadFile{#1.idx}\relax
+ \theCWEBafterindex
+ \par
+ \egroup}
+
+\def\processCWEBsections #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \loadCWEBmacros{#1}
+ \parfillskip = 0pt plus 1fil
+ \parindent = 0pt
+ \let\topsecno=\nullsec
+ \def\note##1%
+ {\quad
+ \bgroup
+ \eightrm
+ ##1~\processCWEBsectionnotes}
+ \def\Q {\CWEBnotesfalse \note{Cited in section}} % crossref for mention of a section
+ \def\Qs{\CWEBnotestrue \note{Cited in sections}} % crossref for mentions of a section
+ \def\U {\CWEBnotesfalse \note{Used in section}} % crossref for use of a section
+ \def\Us{\CWEBnotestrue \note{Used in sections}} % crossref for uses of a section
+ \def\I {\par\hangindent 2em}%
+ \let\*=*
+ \message{Section names:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {sections}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \ReadFile{#1.scn}\relax
+ \par
+ \botofcontents
+ \par
+ \egroup}
+
+\def\processCWEBcontents #1 %
+ {\bgroup
+ \resetCWEBcontext
+ \activateCWEB
+ \loadCWEBmacros{#1}
+ \rightskip = 0pt
+ \hyphenpenalty = 50
+ \tolerance = 200
+ \parindent = 0pt
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \let\ZZ=\contentsline
+ \message{Table of contents:}
+ \marking[CWEBfilename] {#1}
+ \marking[CWEBsectiontitle] {table of contents}
+ \marking[CWEBsectionnumber]{}
+ \marking[CWEBsectiondepth]{}
+ \loadCWEBmacros{#1}
+ \ReadFile{#1.toc}\relax
+ \par
+ \egroup}
+
+\defCWEBmacro\contentsline#1#2#3#4#5%
+ {\ifnum#2=0
+ \smallbreak
+ \fi
+ \line{\consetup{#2}#1
+ \rm
+ \leaders\hbox to .5em{.\hfil}\hfil\
+ {\localcolortrue\goto{#3}[web:#3]}% below: \gotorealpage ? should be changed
+ \hbox to3em{\localcolortrue\hss\gotorealpage{}{}{#5}{\translatednumber[#4]\presetgoto}}}}
+
+%D A last hack, needed because a file can overload of the
+%D above. (Some day: a check like \type{\ifx#1\CWEBdefined}.)
+
+\def\outer#1#2%
+ {\ifx#2\undefined
+ \expandafter#1\expandafter#2%
+ \else
+ \expandafter#1\expandafter\ThrowAway
+ \fi}
+
+\endinput
diff --git a/tex/context/modules/mkiv/m-database.lua b/tex/context/modules/mkiv/m-database.lua
new file mode 100644
index 000000000..91e9636ee
--- /dev/null
+++ b/tex/context/modules/mkiv/m-database.lua
@@ -0,0 +1,132 @@
+if not modules then modules = { } end modules ['m-database'] = {
+ version = 1.001,
+ comment = "companion to m-database.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local sub, gmatch = string.sub, string.gmatch
+local concat = table.concat
+local lpegpatterns, lpegmatch, lpegsplitat = lpeg.patterns, lpeg.match, lpeg.splitat
+local lpegP, lpegC, lpegS, lpegCt, lpegCc, lpegCs = lpeg.P, lpeg.C, lpeg.S, lpeg.Ct, lpeg.Cc, lpeg.Cs
+local stripstring = string.strip
+
+moduledata.database = moduledata.database or { }
+moduledata.database.csv = moduledata.database.csv or { }
+
+-- One also needs to enable context.trace, here we only plug in some code (maybe
+-- some day this tracker will also toggle the main context tracer.
+
+local trace_flush = false trackers.register("module.database.flush", function(v) trace_flush = v end)
+local report_database = logs.reporter("database")
+
+local context = context
+
+local l_tab = lpegpatterns.tab
+local l_space = lpegpatterns.space
+local l_comma = lpegpatterns.comma
+local l_empty = lpegS("\t\n\r ")^0 * lpegP(-1)
+
+local v_yes = interfaces.variables.yes
+
+local separators = { -- not interfaced
+ tab = l_tab,
+ tabs = l_tab^1,
+ comma = l_comma,
+ space = l_space,
+ spaces = l_space^1,
+}
+
+function moduledata.database.csv.process(settings)
+ local data
+ if settings.type == "file" then
+ local filename = resolvers.finders.byscheme("any",settings.database)
+ data = filename ~= "" and io.loaddata(filename)
+ data = data and string.splitlines(data)
+ else
+ data = buffers.getlines(settings.database)
+ end
+ if data and #data > 0 then
+ local catcodes = tonumber(settings.catcodes) or tex.catcodetable
+ context.pushcatcodes(catcodes)
+ if trace_flush then
+ context.pushlogger(report_database)
+ end
+ local separatorchar, quotechar, commentchar = settings.separator, settings.quotechar, settings.commentchar
+ local before, after = settings.before or "", settings.after or ""
+ local first, last = settings.first or "", settings.last or ""
+ local left, right = settings.left or "", settings.right or ""
+ local setups = settings.setups or ""
+ local strip = settings.strip == v_yes or false
+ local command = settings.command or ""
+ separatorchar = (not separatorchar and ",") or separators[separatorchar] or separatorchar
+ local separator = type(separatorchar) == "string" and lpegS(separatorchar) or separatorchar
+ local whatever = lpegC((1 - separator)^0)
+ if quotechar and quotechar ~= "" then
+ local quotedata = nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar = lpegP(chr)
+ local quoteword = lpegCs(((l_space^0 * quotechar)/"") * (1 - quotechar)^0 * ((quotechar * l_space^0)/""))
+ if quotedata then
+ quotedata = quotedata + quoteword
+ else
+ quotedata = quoteword
+ end
+ end
+ whatever = quotedata + whatever
+ end
+ local checker = commentchar ~= "" and lpegS(commentchar)
+ if strip then
+ whatever = whatever / stripstring
+ end
+ if left ~= "" then
+ whatever = lpegCc(left) * whatever
+ end
+ if right ~= "" then
+ whatever = whatever * lpegCc(right)
+ end
+ if command ~= "" then
+ whatever = lpegCc("{") * whatever * lpegCc("}")
+ end
+ whatever = whatever * (separator/"" * whatever)^0
+ if first ~= "" then
+ whatever = lpegCc(first) * whatever
+ end
+ if last ~= "" then
+ whatever = whatever * lpegCc(last)
+ end
+ if command ~= "" then
+ whatever = lpegCs(lpegCc(command) * whatever)
+ else
+ whatever = lpegCs(whatever)
+ end
+ local found = false
+ for i=1,#data do
+ local line = data[i]
+ if not lpegmatch(l_empty,line) and (not checker or not lpegmatch(checker,line)) then
+ if not found then
+ if setups ~= "" then
+ context.begingroup()
+ context.setups { setups }
+ end
+ context(before)
+ found = true
+ end
+ context(lpegmatch(whatever,line))
+ end
+ end
+ if found then
+ context(after)
+ if setups ~= "" then
+ context.endgroup()
+ end
+ end
+ context.popcatcodes()
+ if trace_flush then
+ context.poplogger()
+ end
+ else
+ -- message
+ end
+end
diff --git a/tex/context/modules/mkiv/m-database.mkiv b/tex/context/modules/mkiv/m-database.mkiv
new file mode 100644
index 000000000..cc7dd3d72
--- /dev/null
+++ b/tex/context/modules/mkiv/m-database.mkiv
@@ -0,0 +1,211 @@
+%D \module
+%D [ file=m-database,
+%D version=2010.08.04,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Database Thingies,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D For Mojca.
+
+\registerctxluafile{m-database}{1.001}
+
+\unprotect
+
+\definenamespace
+ [db]
+ [type=module,
+ comment=database module,
+ version=1,
+ name=database,
+ parent=db,
+ setup=yes,
+ command=yes]
+
+\setupdatabase
+ [\c!separator={,},
+ \c!quotechar=,
+ \c!commentchar=,
+ \c!strip=\v!no,
+ \c!before=,
+ \c!after=,
+ \c!first=,
+ \c!last=,
+ \c!left=,
+ \c!right=]
+
+% \let\currentdatabase\empty \the\everypresetdatabase % or just:
+
+\setupdatabase
+ [\c!separator={,}]
+
+\def\module_database_process#1#2#3%
+ {\edef\currentdatabasetype{#1}%
+ \edef\currentdatabase {#2}%
+ \edef\currentdatabasename{#3}%
+ \ifx\currentdatabasename\empty
+ \let\currentdatabasename\currentdatabase
+ \let\currentdatabase\empty
+ \fi
+ \ctxlua{moduledata.database.csv.process {
+ name = "\currentdatabase",
+ type = "\currentdatabasetype",
+ database = "\currentdatabasename",
+ strip = "\databaseparameter\c!strip",
+ separator = \!!bs\databaseparameter\c!separator \!!es,
+ quotechar = \!!bs\databaseparameter\c!quotechar \!!es,
+ commentchar = \!!bs\databaseparameter\c!commentchar\!!es,
+ setups = \!!bs\databaseparameter\c!setups \!!es,
+ before = \!!bs\databaseparameter\c!before \!!es,
+ after = \!!bs\databaseparameter\c!after \!!es,
+ first = \!!bs\databaseparameter\c!first \!!es,
+ last = \!!bs\databaseparameter\c!last \!!es,
+ left = \!!bs\databaseparameter\c!left \!!es,
+ right = \!!bs\databaseparameter\c!right \!!es,
+ command = \!!bs\databaseparameter\c!command \!!es,
+ catcodes = \number\catcodetable
+ }}}
+
+\unexpanded\def\processdatabasebuffer{\dodoubleempty\module_database_process_buffer}
+\unexpanded\def\processdatabasefile {\dodoubleempty\module_database_process_file}
+
+\def\module_database_process_buffer[#1][#2]{\module_database_process{buffer}{#1}{#2}}
+\def\module_database_process_file [#1][#2]{\module_database_process{file} {#1}{#2}}
+
+% for old times sake:
+
+\unexpanded\def\defineseparatedlist {\dodoubleempty\module_database_separated_list_define}
+\unexpanded\def\processseparatedfile{\dodoubleempty\module_database_separated_list_process}
+
+\def\module_database_separated_list_define[#1][#2]%
+ {\definedatabase[#1][#2]%
+ \setuvalue{\e!start#1}{\grabbufferdatadirect{#1}{\e!start#1}{\e!stop#1}}%
+ \setuvalue{\e!stop#1}{\processdatabasebuffer[#1][#1]}}
+
+\def\module_database_separated_list_process[#1][#2]%
+ {\processdatabasefile[#1][#2]}
+
+\unexpanded\def\startseparatedlist[#1]% to be interfaced
+ {\unexpanded\def\stopseparatedlist{\processdatabasebuffer[#1][#1]}%
+ \grabbufferdatadirect{#1}{startseparatedlist}{stopseparatedlist}}
+
+\let\setupseparatedlist\setupdatabase
+
+\protect
+
+\continueifinputfile{m-database.mkiv}
+
+\starttext
+
+% m-database.txt
+%
+% 1,2,3,4,5
+% 6,7,8,"9,x",0
+% A,B,C,D
+% E,,F
+% G
+
+\definedatabase[test]
+
+\setupdatabase
+ [test]
+ [separator={,},
+ quotechar={"},
+ before={<},
+ after={>},
+ first={\endgraf[},
+ last={]\endgraf},
+ left={ (},
+ right={) }]
+
+\startbuffer[testbuffer]
+1,2,3,4,5
+6,7,8,"9,x",0
+A,B,C,D
+E,,F
+G
+\stopbuffer
+
+\processdatabasebuffer[test][testbuffer]
+
+\processdatabasefile[test][m-database.txt]
+
+\defineseparatedlist
+ [CSV]
+ [separator={,},
+ before=\bTABLE,after=\eTABLE,
+ first=\bTR,last=\eTR,
+ left=\bTD,right=\eTD]
+
+% \startseparatedlist[CSV]
+% a,b,c
+% d,e,f
+% \stopseparatedlist
+
+\startCSV
+a,b,c
+d,e,f
+\stopCSV
+
+\defineseparatedlist
+ [CSV]
+ [separator={,+},quotechar={"'},commentchar=\letterhash,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate,
+ first=\NC,last=\NR,
+ left=,right=\NC]
+
+\startCSV
+#a,b,"c,d"
+a,b,"c,d"
+a,'b,c',d
+"a,b"+c+d
+\stopCSV
+
+\defineseparatedlist
+ [CSV]
+ [separator=space,
+ first=\NC,last=\NR,
+ left=,right=\NC,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate]
+
+\startCSV
+a b c
+d e f
+\stopCSV
+
+\startsetups csv:unix
+ \catcode\hashasciicode\commentcatcode
+\stopsetups
+
+\defineseparatedlist
+ [CSV]
+ [setups=csv:unix,
+ separator={,},
+ first=\NC,last=\NR,
+ left=,right=\NC,
+ before={\starttabulate[|l|l|l|]},after=\stoptabulate]
+
+\processseparatedfile[CSV][m-database.txt]
+
+\defineseparatedlist[CSV]
+ [separator=comma,
+ before=\bTABLE, after=\eTABLE,
+ first=\bTR, last=\eTR,
+ left=\bTD, right=\eTD]
+
+\startCSV
+a,b,c,č
+d,e,f,š
+\stopCSV
+
+\startseparatedlist[CSV]
+a,b,c,č
+d,e,f,š
+\stopseparatedlist
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-directives.mkiv b/tex/context/modules/mkiv/m-directives.mkiv
new file mode 100644
index 000000000..8b551b27a
--- /dev/null
+++ b/tex/context/modules/mkiv/m-directives.mkiv
@@ -0,0 +1,3 @@
+\starttext
+ \showdirectives
+\stoptext
diff --git a/tex/context/modules/mkiv/m-educat.mkiv b/tex/context/modules/mkiv/m-educat.mkiv
new file mode 100644
index 000000000..93b1a6c5d
--- /dev/null
+++ b/tex/context/modules/mkiv/m-educat.mkiv
@@ -0,0 +1,217 @@
+%D \module
+%D [ file=m-educat,
+%D version=2003.03.05,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Educational Extras,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module will collect a few macros cq.\ definitions
+%D meant for educational use. Most of the code has been laying
+%D around for some time and has been (or is still) used in
+%D \PRAGMA\ projects.
+
+\unprotect
+
+\definesystemvariable{iv}
+
+\definecolor [answerareacolor] [s=.90]
+\definecolor [answerlinecolor] [white]
+
+\definetextbackground
+ [\v!answerarea]
+ [\c!location=\v!text,
+ \c!n=0,
+ \c!frame=\v!off,
+ \c!framecolor=answerlinecolor,
+ \c!rulethickness=2pt,
+ \c!background=\v!color,
+ \c!backgroundcolor=answerareacolor,
+ \c!alternative=2] % betweenline
+
+% n=gedwongen
+% m=extra auto
+
+\def\setupanswerarea
+ {\setuptextbackground[\v!answerarea]}
+
+\setvalue\e!answerspace
+ {\dosingleempty\doanswerspace}
+
+\def\doanswerspace[#1]%
+ {\begingroup
+ \dontcomplain
+ \setupanswerarea
+ [\c!n=0,\c!m=,#1,\c!location=\v!text]%
+ \doifelsenothing{\textbackgroundparameter\c!m}
+ {\expandafter\donoanswerspace}
+ {\expandafter\dodoanswerspace}%
+ [#1]}
+
+\def\donoanswerspace[#1]#2%
+ {\setupthinrules
+ [\c!alternative=\textbackgroundparameter\c!alternative,
+ \c!color=\textbackgroundparameter\c!framecolor,
+ \c!background=\textbackgroundparameter\c!background,
+ \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor,
+ \c!rulethickness=\textbackgroundparameter\c!rulethickness]%
+ \doifelse{\textbackgroundparameter\c!n}{*}
+ {\thinrule
+ \par}
+ {\scratchcounter0\textbackgroundparameter\c!n\relax
+ % tricky, guess
+ \def\processisolatedword##1%
+ {\setbox\scratchbox=\hbox{##1}%
+ \vbox{\hsize\wd\scratchbox\thinrule
+ \ifcase\scratchcounter\else
+ \setbox\scratchbox=\hbox{\space}%
+ \nobreak\hskip\zeropoint \!!minus \wd\scratchbox
+ \vbox{\hsize\wd\scratchbox\thinrule}%
+ \fi}}%
+ \processisolatedwords{#2}\processisolatedword
+ % so far
+ \ifcase\scratchcounter \else \ifnum\scratchcounter<3
+ \nobreak \vbox{\hsize\scratchcounter em\thinrule}%
+ \else % more
+ \advance \scratchcounter -2
+ \dorecurse\scratchcounter{\allowbreak\vbox{\hsize1em\thinrule}}%
+ \nobreak \vbox{\hsize2em\thinrule}%
+ \fi \fi}%
+ \endgroup}
+
+\def\dodoanswerspace[#1]#2% m case
+ {\getvalue{\e!start\v!answerarea}%
+ #2%
+ \doifelse{\textbackgroundparameter\c!m}{*}
+ {\hfill\strut
+ \getvalue{\e!stop\v!answerarea}%
+ \par}
+ {\scratchcounter0\textbackgroundparameter\c!m\relax
+ \ifcase\scratchcounter \else \ifnum\scratchcounter<3
+ \nobreak \hbox to \scratchcounter em{\strut\hss}%
+ \else % more
+ \advance \scratchcounter -2
+ \dorecurse\scratchcounter{\allowbreak\hbox to 1em{\strut\hss}}%
+ \nobreak \hbox to 2em{\strut\hss}%
+ \fi \fi
+ \getvalue{\e!stop\v!answerarea}}%
+ \endgroup}
+
+\setvalue{\e!start\e!answerlines}%
+ {\dosingleempty\dostartanswerlines}
+
+\def\dostartanswerlines[#1]%
+ {\begingroup
+ \dontcomplain
+ \setupanswerarea
+ [\c!n=0,\c!m=,#1,\c!location=\v!text]%
+ \doifnot{\textbackgroundparameter\c!option}\v!joinedup\softbreak
+ \doifelsenothing{\textbackgroundparameter\c!m}
+ {\expandafter\donostartanswerlines}
+ {\expandafter\dodostartanswerlines}%
+ [#1]}
+
+\def\donostartanswerlines[#1]%
+ {\setupthinrules
+ [\c!alternative=\textbackgroundparameter\c!alternative,
+ \c!color=\textbackgroundparameter\c!framecolor,
+ \c!background=\textbackgroundparameter\c!background,
+ \c!backgroundcolor=\textbackgroundparameter\c!backgroundcolor,
+ \c!rulethickness=\textbackgroundparameter\c!rulethickness]%
+ \thinrules[\c!n=\textbackgroundparameter\c!n]\par
+ \endgroup
+ \grabuntil{\e!stop\e!answerlines}}
+
+\def\dodostartanswerlines[#1]%
+ {\begingroup
+ \getvalue{\e!start\v!answerarea}%
+ \ignorespaces}
+
+\setvalue{\e!stop\e!answerlines}%
+ {\scratchcounter0\textbackgroundparameter\c!m\relax
+ % a \softbreak is more efficient in pos dan \par
+ \ifcase\scratchcounter
+ % nothing
+ \or
+ \softbreak
+ \else
+ \softbreak
+ \advance \scratchcounter \minusone
+ \dorecurse\scratchcounter{\strut\hfill\strut\softbreak}%
+ \fi
+ \strut\hfill\strut
+ \getvalue{\e!stop\v!answerarea}%
+ \par\endgroup\endgroup}
+
+\setvalue\e!answerlines
+ {\dosingleempty\doanswerlines}
+
+\def\doanswerlines[#1]#2%
+ {\getvalue{\e!start\e!answerlines}[#1]%
+ #2%
+ \getvalue{\e!stop\e!answerlines}}
+
+\protect \doifnotmode{demo}{\endinput}
+
+%D Test materiaal.
+
+\starttext
+
+\startnotmode[answers]
+
+ \setupanswerarea[level=+1]
+
+\stopnotmode
+
+\setupcolors[state=start]
+
+test test test \answerspace [n=10] {Whow}. test test test
+test tets test test \answerspace [n=10] {Whow}. test test
+test test tets test test \answerspace [n=10] {Whow}. test
+test test test tets test test \answerspace [n=10] {Whow}.
+test test test test test test \answerspace [n=*] {Whow.}
+
+test test test test test test test \startanswerlines
+[n=3] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=0] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=1] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[n=3,alternative=2] What A Junk Answer \stopanswerlines
+
+\startitemize[paragraph]
+\item \startanswerlines [option=seried,n=2] xxx \stopanswerlines
+\stopitemize
+
+test test test \answerspace [m=10] {Whow}. test test test
+test tets test test \answerspace [m=10] {Whow}. test test
+test test tets test test \answerspace [m=10] {Whow}. test
+test test test tets test test \answerspace [m=10] {Whow}.
+test test test test test test \answerspace [m=*] {Whow.}
+
+test test test test test test test \startanswerlines
+[m=2] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=0] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=1] What A Junk Answer \stopanswerlines
+
+test test test test test test test \startanswerlines
+[m=2,alternative=2] What A Junk Answer \stopanswerlines
+
+\startitemize[paragraph]
+\item \startanswerlines [option=seried,m=2] xxx \stopanswerlines
+\stopitemize
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-escrito.lua b/tex/context/modules/mkiv/m-escrito.lua
new file mode 100644
index 000000000..0d7a04741
--- /dev/null
+++ b/tex/context/modules/mkiv/m-escrito.lua
@@ -0,0 +1,7088 @@
+if not modules then modules = { } end modules ['m-escrito'] = {
+ version = 1.001,
+ comment = "companion to m-escrito.mkiv",
+ author = "Taco Hoekwater (BitText) and Hans Hagen (PRAGMA-ADE)",
+ license = "see below and context related readme files"
+}
+
+-- This file is derived from Taco's escrito interpreter. Because the project was
+-- more or less stopped, after some chatting we decided to preserve the result
+-- and make it useable in ConTeXt. Hans went over all code, fixed a couple of
+-- things, messed other things, made the code more efficient, wrapped all in
+-- some helpers. So, a diff between the original and this file is depressingly
+-- large. This means that you shouldn't bother Taco with the side effects (better
+-- or worse) that result from this.
+
+-- Fonts need some work and I will do that when needed. I might cook up something
+-- similar to what we do with MetaFun. First I need to run into a use case. After
+-- all, this whole exercise is just that: getting an idea of what processing PS
+-- code involves.
+
+-- Here is the usual copyright blabla:
+--
+-- Copyright 2010 Taco Hoekwater <taco@luatex.org>. All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without modification,
+-- are permitted provided that the following conditions are met:
+--
+-- 1. Redistributions of source code must retain the above copyright notice, this
+-- list of conditions and the following disclaimer.
+--
+-- 2. Redistributions in binary form must reproduce the above copyright notice, this
+-- list of conditions and the following disclaimer in the documentation and/or
+-- other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+-- SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+-- OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+-- DAMAGE.
+
+-- We use a couple of do..ends later on because this rather large file has too many
+-- locals otherwise. Possible optimizations are using insert/remove and getting rid
+-- of the VM calls (in direct mode they are no-ops anyway). We can also share some
+-- more code here and there.
+
+local type, unpack, tonumber, tostring, next = type, unpack, tonumber, tostring, next
+
+local format = string.format
+local gmatch = string.gmatch
+local match = string.match
+local sub = string.sub
+local char = string.char
+local byte = string.byte
+
+local insert = table.insert
+local remove = table.remove
+local concat = table.concat
+local reverse = table.reverse
+
+local abs = math.abs
+local ceil = math.ceil
+local floor = math.floor
+local sin = math.sin
+local cos = math.cos
+local rad = math.rad
+local sqrt = math.sqrt
+local atan2 = math.atan2
+local tan = math.tan
+local deg = math.deg
+local pow = math.pow
+local log = math.log
+local log10 = math.log10
+local random = math.random
+local setranseed = math.randomseed
+
+local bitand = bit32.band
+local bitor = bit32.bor
+local bitxor = bit32.bxor
+local bitrshift = bit32.rshift
+local bitlshift = bit32.lshift
+
+local lpegmatch = lpeg.match
+local Ct, Cc, Cs, Cp, C, R, S, P, V = lpeg.Ct, lpeg.Cc, lpeg.Cs, lpeg.Cp, lpeg.C, lpeg.R, lpeg.S, lpeg.P, lpeg.V
+
+local formatters = string.formatters
+local setmetatableindex = table.setmetatableindex
+
+-- Namespace
+
+-- HH: Here we assume just one session. If needed we can support more (just a matter
+-- of push/pop) but it makes the code more complex and less efficient too.
+
+escrito = { }
+
+----- escrito = escrito
+local initializers = { }
+local devices = { }
+local specials
+
+local DEBUG = false -- these will become trackers if needed
+local INITDEBUG = false -- these will become trackers if needed
+local MAX_INT = 0x7FFFFFFF -- we could have slightly larger ints because lua internally uses doubles
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ specials = nil
+ else
+ specials = { }
+ end
+end
+
+local devicename
+local device
+
+-- "boundingbox",
+-- "randomseed",
+
+-- Composite objects
+--
+-- Arrays, dicts and strings are stored in VM. To do this, VM is an integer-indexed table. This appears
+-- a bit silly in lua because we are actually just emulating a C implementation detail (pointers) but it
+-- is documented behavior. There is also supposed to be a VM stack, but I will worry about that when it
+-- becomes time to implement save/restore. (TH)
+
+local VM -- todo: just a hash
+
+initializers[#initializers+1] = function()
+ VM = { }
+end
+
+local directvm = true
+
+local add_VM, get_VM
+
+if directvm then -- if ok then we remove the functions
+
+ add_VM = function(a)
+ return a
+ end
+ get_VM = function(i)
+ return i
+ end
+
+else
+
+ add_VM = function(a)
+ local n = #VM + 1
+ VM[n] = a
+ return n
+ end
+
+ get_VM = function(i)
+ return VM[i]
+ end
+
+end
+
+-- Execution stack
+
+local execstack
+local execstackptr
+local do_exec
+local next_object
+local stopped
+
+initializers[#initializers+1] = function()
+ execstack = { }
+ execstackptr = 0
+ stopped = false
+end
+
+local function pop_execstack()
+ if execstackptr > 0 then
+ local value = execstack[execstackptr]
+ execstackptr = execstackptr - 1
+ return value
+ else
+ return nil -- stackunderflow
+ end
+end
+
+local function push_execstack(v)
+ execstackptr = execstackptr + 1
+ execstack[execstackptr] = v
+end
+
+-- Operand stack
+--
+-- Most operand and exec stack entries are four-item arrays:
+--
+-- [1] = "[integer|real|boolean|name|mark|null|save|font]" (a postscript interpreter type)
+-- [2] = "[unlimited|read-only|execute-only|noaccess]"
+-- [3] = "[executable|literal]" (exec attribute)
+-- [4] = value (a VM index inthe case of names)
+--
+-- But there are some exceptions.
+--
+-- Dictionaries save the access attribute inside the value
+--
+-- [1] = "dict"
+-- [2] = irrelevant
+-- [3] = "[executable|literal]"
+-- [4] = value (a VM index)
+--
+-- Operators have a fifth item:
+--
+-- [1] = "operator"
+-- [2] = "[unlimited|read-only|execute-only|noaccess]"
+-- [3] = "[executable|literal]"
+-- [4] = value
+-- [5] = identifier (the operator name)
+--
+-- Strings and files have a fifth and a sixth item, the fifth of which is
+-- only relevant if the exec attribute is 'executable':
+--
+-- [1] = "[string|file]"
+-- [2] = "[unlimited|read-only|execute-only|noaccess]"
+-- [3] = "[executable|literal]"
+-- [4] = value (a VM index) (for input files, this holds the whole file)
+-- [5] = exec-index
+-- [6] = length
+-- [7] = iomode (for files only)
+-- [8] = filehandle (for files only)
+--
+-- Arrays also have a seven items, the fifth is only relevant if
+-- the exec attribute is 'executable', and the seventh is used to differentiate
+-- between direct and indirect interpreter views of the object.
+--
+-- [1] = "array"
+-- [2] = "[unlimited|read-only|execute-only|noaccess]"
+-- [3] = "[executable|literal]"
+-- [4] = value (a VM index)
+-- [5] = exec-index
+-- [6] = length (a VM index)
+-- [7] = "[d|i]" (direct vs. indirect)
+--
+-- The exec stack also has an object with [1] == ".stopped", which is used
+-- for "stopped" execution contexts
+
+local opstack
+local opstackptr
+
+initializers[#initializers+1] = function()
+ opstack = { }
+ opstackptr = 0
+end
+
+local function pop_opstack()
+ if opstackptr > 0 then
+ local value = opstack[opstackptr]
+ opstackptr = opstackptr - 1
+ return value
+ else
+ return nil -- stackunderflow
+ end
+end
+
+local function push_opstack(v)
+ opstackptr = opstackptr + 1
+ opstack[opstackptr] = v
+end
+
+local function check_opstack(n)
+ return opstackptr >= n
+end
+
+local function get_opstack()
+ if opstackptr > 0 then
+ return opstack[opstackptr]
+ else
+ return nil -- stackunderflow
+ end
+end
+
+-- In case of error, the interpreter has to restore the opstack
+
+local function copy_opstack()
+ local t = { }
+ for n=1,opstackptr do
+ local sn = opstack[n]
+ t[n] = { unpack(sn) }
+ end
+ return t
+end
+
+local function set_opstack(new)
+ opstackptr = #new
+ opstack = new
+end
+
+-- Dict stack
+
+local dictstack
+local dictstackptr
+
+initializers[#initializers+1] = function()
+ dictstack = { }
+ dictstackptr = 0
+end
+
+-- this finds a name in the current dictionary stack
+
+local function lookup(name)
+ for n=dictstackptr,1,-1 do
+ local found = get_VM(dictstack[n])
+ if found then
+ local dict = found.dict
+ if dict then
+ local d = dict[name]
+ if d then
+ return d, n
+ end
+ end
+ end
+ end
+ return nil
+end
+
+-- Graphics state stack
+
+-- device backends are easier if gsstate items use bare data instead of
+-- ps objects, much as possible
+
+-- todo: just use one color array
+
+local gsstate
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ gsstate = nil
+ else
+ gsstate = {
+ matrix = { 1, 0, 0, 1, 0, 0 },
+ color = {
+ gray = 0,
+ hsb = { },
+ rgb = { },
+ cmyk = { },
+ type = "gray"
+ },
+ position = { }, -- actual x and y undefined
+ path = { },
+ clip = { },
+ font = nil,
+ linewidth = 1,
+ linecap = 0,
+ linejoin = 0,
+ screen = nil, -- by default, we don't use a screen, which matches "1 0 {pop}"
+ transfer = nil, -- by default, we don't have a transfer function, which matches "{}"
+ flatness = 0,
+ miterlimit = 10,
+ dashpattern = { },
+ dashoffset = 0,
+ }
+ end
+end
+
+local function copy_gsstate()
+ local old = gsstate
+ local position = old.position
+ local matrix = old.matrix
+ local color = old.color
+ local rgb = color.rgb
+ local cmyk = color.cmyk
+ local hsb = color.hsb
+ return {
+ matrix = { matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6] },
+ color = {
+ type = color.type,
+ gray = color.gray,
+ hsb = { hsb[1], hsb[2], hsb[3] },
+ rgb = { rgb[1], rgb[2], rgb[3] },
+ cmyk = { cmyk[1], cmyk[2], cmyk[3], cmyk[4] },
+ },
+ position = { position[1], position[2] },
+ path = { unpack (old.path) },
+ clip = { unpack (old.clip) },
+ font = old.font,
+ linewidth = old.linewidth,
+ linecap = old.linecap,
+ linejoin = old.linejoin,
+ screen = old.screen,
+ transfer = nil,
+ flatness = old.flatness,
+ miterlimit = old.miterlimit,
+ dashpattern = { },
+ dashoffset = 0,
+ }
+end
+
+-- gsstack entries are of the form
+-- [1] "[save|gsave]"
+-- [2] {gsstate}
+
+local gsstack
+local gsstackptr
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ gsstack = nil
+ gsstackptr = nil
+ else
+ gsstack = { }
+ gsstackptr = 0
+ end
+end
+
+local function push_gsstack(v)
+ gsstackptr = gsstackptr + 1
+ gsstack[gsstackptr] = v
+end
+
+local function pop_gsstack()
+ if gsstackptr > 0 then
+ local v = gsstack[gsstackptr]
+ gsstackptr = gsstackptr - 1
+ return v
+ end
+end
+
+-- Currentpage
+
+local currentpage
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ currentpage = nil
+ else
+ currentpage = { }
+ end
+end
+
+-- Errordict
+
+-- The standard errordict entry. The rest of these dictionaries will be filled
+-- in the new() function.
+
+local errordict
+local dicterror
+
+-- find an error handler
+
+local function lookup_error(name)
+ local dict = get_VM(errordict).dict
+ return dict and dict[name]
+end
+
+-- error handling and reporting
+
+local report = logs.reporter("escrito")
+
+local function ps_error(a)
+ -- can have print hook
+ return false, a
+end
+
+-- Most entries in systemdict are operators, and the operators each have their own
+-- implementation function. These functions are grouped by category cf. the summary
+-- in the Adobe PostScript reference manual, the creation of the systemdict entries
+-- is alphabetical.
+--
+-- In the summary at the start of the operator sections, the first character means:
+--
+-- "-" => todo
+-- "+" => done
+-- "*" => partial
+-- "^" => see elsewhere
+
+local operators = { }
+
+-- Operand stack manipulation operators
+--
+-- +pop +exch +dup +copy +index +roll +clear +count +mark +cleartomark +counttomark
+
+function operators.pop()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ return true
+end
+
+function operators.exch()
+ if opstackptr < 2 then
+ return ps_error('stackunderflow')
+ end
+ local prv = opstackptr-1
+ opstack[opstackptr], opstack[prv] = opstack[prv], opstack[opstackptr]
+ return true
+end
+
+function operators.dup()
+ if opstackptr < 1 then
+ return ps_error('stackunderflow')
+ end
+ local nxt = opstackptr+1
+ opstack[nxt] = opstack[opstackptr]
+ opstackptr = nxt
+ return true
+end
+
+function operators.copy()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'integer' then
+ local va = a[4]
+ if va < 0 then
+ return ps_error('typecheck')
+ end
+ local thestack = opstackptr
+ if va > thestack then
+ return ps_error('stackunderflow')
+ end
+ -- use for loop
+ local n = thestack - va + 1
+ while n <= thestack do
+ local b = opstack[n]
+ local tb = b[1]
+ if tb == 'array' or tb == 'string' or tb == 'dict' or tb == 'font' then
+ b = { tb, b[2], b[3], add_VM(get_VM(b[4])), b[5], b[6], b[7] }
+ end
+ push_opstack(b)
+ n = n + 1
+ end
+ elseif ta == 'dict' then
+ local b = a
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'dict' then
+ return ps_error('typecheck')
+ end
+ local thedict = get_VM(b[4])
+ local tobecopied = get_VM(a[4])
+ if thedict.maxsize < tobecopied.size then
+ return ps_error('rangecheck')
+ end
+ if thedict.size ~= 0 then
+ return ps_error('typecheck')
+ end
+ local access = thedict.access
+ if access == 'read-only' or access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local dict = { }
+ for k, v in next, tobecopied.dict do
+ dict[k] = v -- fixed, was thedict[a], must be thedict.dict
+ end
+ thedict.access = tobecopied.access
+ thedict.size = tobecopied.size
+ thedict.dict = dict
+ b = { b[1], b[2], b[3], add_VM(thedict) }
+ push_opstack(b)
+ elseif ta == 'array' then
+ local b = a
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if b[6] < a[6] then
+ return ps_error('rangecheck')
+ end
+ local access = b[2]
+ if access == 'read-only' or access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local array = { }
+ local thearray = get_VM(b[4])
+ local tobecopied = get_VM(a[4])
+ for k, v in next, tobecopied do
+ array[k] = v
+ end
+ b = { b[1], b[2], b[3], add_VM(array), a[5], a[6], a[7] } -- fixed, was thearray
+ push_opstack(b)
+ elseif ta == 'string' then
+ local b = a
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if b[6] < a[6] then
+ return ps_error('rangecheck')
+ end
+ local access = b[2]
+ if access == 'read-only' or access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local thestring = get_VM(b[4])
+ local repl = get_VM(a[4])
+ VM[b[4]] = repl .. sub(thestring,#repl+1,-1)
+ b = { b[1], b[2], b[3], add_VM(repl), a[5], b[6] }
+ push_opstack(b)
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.index()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not ta == 'integer' then
+ return ps_error('typecheck')
+ end
+ local n = a[4]
+ if n < 0 then
+ return ps_error('rangecheck')
+ end
+ if n >= opstackptr then
+ return ps_error('stackunderflow')
+ end
+ push_opstack(opstack[opstackptr-n])
+ return true
+end
+
+function operators.roll()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if a[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local stackcount = a[4]
+ if stackcount < 0 then
+ return ps_error('rangecheck')
+ end
+ if stackcount > opstackptr then
+ return ps_error('stackunderflow')
+ end
+ local rollcount = b[4]
+ if rollcount == 0 then
+ return true
+ end
+ if rollcount > 0 then
+ -- can be simplified
+ while rollcount > 0 do
+ local oldtop = opstack[opstackptr]
+ local n = 0
+ while n < stackcount do
+ opstack[opstackptr-n] = opstack[opstackptr-n-1]
+ n = n + 1
+ end
+ opstack[opstackptr-(stackcount-1)] = oldtop
+ rollcount = rollcount - 1
+ end
+ else
+ -- can be simplified
+ while rollcount < 0 do
+ local oldbot = opstack[opstackptr-stackcount+1]
+ local n = stackcount - 1
+ while n > 0 do
+ opstack[opstackptr-n] = opstack[opstackptr-n+1]
+ n = n - 1
+ end
+ opstack[opstackptr] = oldbot
+ rollcount = rollcount + 1
+ end
+ end
+ return true
+end
+
+function operators.clear()
+ opstack = { } -- or just keep it
+ opstackptr = 0
+ return true
+end
+
+function operators.count()
+ push_opstack { 'integer', 'unlimited', 'literal', opstackptr }
+ return true
+end
+
+function operators.mark()
+ push_opstack { 'mark', 'unlimited', 'literal', null }
+end
+
+operators.beginarray = operators.mark
+
+function operators.cleartomark()
+ while opstackptr > 0 do
+ local val = pop_opstack()
+ if not val then
+ return ps_error('unmatchedmark')
+ end
+ if val[1] == 'mark' then
+ return true
+ end
+ end
+ return ps_error('unmatchedmark')
+end
+
+function operators.counttomark()
+ local v = 0
+ for n=opstackptr,1,-1 do
+ if opstack[n][1] == 'mark' then
+ push_opstack { 'integer', 'unlimited', 'literal', v }
+ return true
+ end
+ v = v + 1
+ end
+ return ps_error('unmatchedmark')
+end
+
+-- Arithmetic and math operators
+--
+-- +add +div +idiv +mod +mul +sub +abs +neg +ceiling +floor +round +truncate +sqrt +atan +cos
+-- +sin +exp +ln +log +rand +srand +rrand
+
+function operators.add()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = a[4] + b[4]
+ push_opstack {
+ (ta == 'real' or tb == 'real' or c > MAX_INT) and "real" or "integer",
+ 'unlimited', 'literal', c
+ }
+ return true
+end
+
+function operators.sub()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = a[4] - b[4]
+ push_opstack {
+ (ta == 'real' or tb == 'real' or c > MAX_INT) and "real" or "integer",
+ 'unlimited', 'literal', c
+ }
+ return true
+end
+
+function operators.div()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if vb == 0 then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'real', 'unlimited', 'literal', va / vb }
+ return true
+end
+
+function operators.idiv()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if tb ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if ta ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if vb == 0 then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', floor(va / vb) }
+ return true
+end
+
+function operators.mod()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if tb ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if ta ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if vb == 0 then
+ return ps_error('undefinedresult')
+ end
+ local neg = false
+ local v
+ if va < 0 then
+ v = -va
+ neg = true
+ else
+ v = va
+ end
+ local c = v % abs(vb)
+ if neg then
+ c = -c
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.mul()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = a[4] * b[4]
+ push_opstack {
+ (ta == 'real' or tb == 'real' or abs(c) > MAX_INT) and 'real' or 'integer',
+ 'unlimited', 'literal', c
+ }
+ return true
+end
+
+function operators.abs()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ local c = abs(v)
+ push_opstack {
+ (ta == 'real' or v == -(MAX_INT+1)) and 'real' or 'integer', -- hm, v or c
+ 'unlimited', 'literal', c
+ }
+ return true
+end
+
+function operators.neg()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ push_opstack {
+ (ta == 'real' or v == -(MAX_INT+1)) and 'real' or 'integer',
+ 'unlimited', 'literal', -v
+ }
+ return true
+end
+
+function operators.ceiling()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = ceil(a[4])
+ push_opstack { ta, 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.floor()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = floor(a[4])
+ push_opstack { ta, 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.round()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = floor(a[4]+0.5)
+ push_opstack { ta, 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.truncate()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ local c =v < 0 and -floor(-v) or floor(v)
+ push_opstack { ta, 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.sqrt()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ if v < 0 then
+ return ps_error('rangecheck')
+ end
+ local c = sqrt(v)
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.atan()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if va == 0 and vb == 0 then
+ return ps_error('undefinedresult')
+ end
+ local c = deg(atan2(rad(va),rad(vb)))
+ if c < 0 then
+ c = c + 360
+ end
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.sin()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = sin(rad(a[4]))
+ -- this is because double calculation introduces a small error
+ if abs(c) < 1.0e-16 then
+ c = 0
+ end
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.cos()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local c = cos(rad(a[4]))
+ -- this is because double calculation introduces a small error
+ if abs(c) < 1.0e-16 then
+ c = 0
+ end
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.exp()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if va < 0 and floor(vb) ~= vb then
+ return ps_error('undefinedresult')
+ end
+ local c = pow(va,vb)
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.ln()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ if v <= 0 then
+ return ps_error('undefinedresult')
+ end
+ local c = log(v)
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.log()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = a[4]
+ if v <= 0 then
+ return ps_error('undefinedresult')
+ end
+ local c = log10(v)
+ push_opstack { 'real', 'unlimited', 'literal', c }
+ return true
+end
+
+escrito.randomseed = os.time()
+
+-- this interval is one off, but that'll do
+
+function operators.rand()
+ local c = random(MAX_INT) - 1
+ push_opstack { 'integer', 'unlimited', 'literal', c }
+ return true
+end
+
+function operators.srand()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ escrito.randomseed = a[4]
+ setranseed(escrito.randomseed)
+ return true
+end
+
+function operators.rrand()
+ push_opstack { 'integer', 'unlimited', 'literal', escrito.randomseed }
+ return true
+end
+
+-- Array operators
+--
+-- +array ^[ +] +length +get +put +getinterval +putinterval +aload +astore ^copy +forall
+
+function operators.array()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local t = a[1]
+ local v = a[4]
+ if t ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if v < 0 then
+ return ps_error('rangecheck')
+ end
+ local array = { }
+ for i=1,v do
+ array[n] = { 'null', 'unlimited', 'literal', true } -- todo: share this one
+ end
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(array), 0, v, 'd'}
+end
+
+function operators.endarray()
+ local n = opstackptr
+ while n > 0 do
+ if opstack[n][1] == 'mark' then
+ break
+ end
+ n = n - 1
+ end
+ if n == 0 then
+ return ps_error('unmatchedmark')
+ end
+ local top = opstackptr
+ local i = opstackptr - n
+ local array = { }
+ while i > 0 do
+ array[i] = pop_opstack()
+ i = i - 1
+ end
+ pop_opstack() -- pop the mark
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(array), #array, #array, 'd' }
+end
+
+function operators.length()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local access = a[2]
+ if access == "noaccess" or access == "executeonly" then
+ return ps_error('invalidaccess')
+ end
+ local ta = a[1]
+ local va = a[4]
+ if ta == "dict" or ta == "font" then
+ va = get_VM(va).size
+ elseif ta == "array" or ta == "string" then
+ va = get_VM(va)
+ va = #va
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', va }
+ return true
+end
+
+function operators.get()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local access = a[2]
+ if access == "noaccess" or access == "execute-only" then
+ return ps_error('invalidaccess')
+ end
+ local ta = a[1]
+ local va = a[4]
+ if ta == "dict" then
+ local dict = get_VM(va)
+ local key = b
+ local tb = b[1]
+ local vb = b[4]
+ if tb == "string" or tb == "name" then
+ key = get_VM(vb)
+ end
+ local ddk = dict.dict[key]
+ if ddk then
+ push_opstack(ddk)
+ else
+ return ps_error('undefined')
+ end
+ elseif ta == "array" then
+ local tb = b[1]
+ local vb = b[4]
+ if tb ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if vb < 0 or vb >= a[6] then
+ return ps_error('rangecheck')
+ end
+ local array = get_VM(va)
+ local index = vb + 1
+ push_opstack(array[index])
+ elseif ta == "string" then
+ local tb = b[1]
+ local vb = b[4]
+ if tb ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if vb < 0 or vb >= a[6] then
+ return ps_error('rangecheck')
+ end
+ local thestring = get_VM(va)
+ local index = vb + 1
+ local c = sub(thestring,index,index)
+ push_opstack { 'integer', 'unlimited', 'literal', byte(c) }
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.put()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == "dict" then
+ local dict = get_VM(a[4])
+ if dict.access ~= 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ local key = b
+ local bt = b[1]
+ if bt == "string" or bt == "name" then
+ key = get_VM(b[4])
+ end
+ local dd = dict.dict
+ local ds = dict.size
+ local ddk = dd[key]
+ if not ddk and (ds == dict.maxsize) then
+ return ps_error('dictfull')
+ end
+ if c[1] == 'array' then
+ c[7] = 'i'
+ end
+ if not ddk then
+ dict.size = ds + 1
+ end
+ dd[key] = c
+ elseif ta == "array" then
+ if a[2] ~= 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ if b[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local va, vb = a[4], b[4]
+ if vb < 0 or vb >= a[6] then
+ return ps_error('rangecheck')
+ end
+ local vm = VM[va]
+ local vi = bv + 1
+ if vm[vi][1] == 'null' then
+ a[5] = a[5] + 1
+ end
+ vm[vi] = c
+ elseif ta == "string" then
+ if a[2] ~= 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ if b[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if c[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local va, vb, vc = a[4], b[4], c[4]
+ if vb < 0 or vb >= a[6] then
+ return ps_error('rangecheck')
+ end
+ if vc < 0 or vc > 255 then
+ return ps_error('rangecheck')
+ end
+ local thestring = get_VM(va)
+ VM[va] = sub(thestring,1,vb) .. char(vc) .. sub(thestring,vb+2)
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.getinterval()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc = a[1], b[1], c[1]
+ local aa, ab, ac = a[2], b[2], c[2]
+ local va, vb, vc = a[4], b[4], c[4]
+ if ta ~= "array" and ta ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if tb ~= 'integer' or tc ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if aa == "execute-only" or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ if vb < 0 or vc < 0 or vb + vc >= a[6] then
+ return ps_error('rangecheck')
+ end
+ -- vb : start
+ -- vc : number
+ if ta == 'array' then
+ local array = get_VM(va)
+ local subarray = { }
+ local index = 1
+ while index <= vc do
+ subarray[index] = array[index+vb]
+ index = index + 1
+ end
+ push_opstack { 'array', aa, a[3], add_VM(subarray), vc, vc, 'd' }
+ else
+ local thestring = get_VM(va)
+ local newstring = sub(thestring,vb+1,vb+vc)
+ push_opstack { 'string', aa, a[3], add_VM(newstring), vc, vc }
+ end
+ return true
+end
+
+function operators.putinterval()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc = a[1], b[1], c[1]
+ local aa, ab, ac = a[2], b[2], c[2]
+ local va, vb, vc = a[4], b[4], c[4]
+ if ta ~= "array" and ta ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if tc ~= "array" and tc ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if ta ~= tc then
+ return ps_error('typecheck')
+ end
+ if aa ~= "unlimited" then
+ return ps_error('invalidaccess')
+ end
+ if tb ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if vb < 0 or vb + c[6] >= a[6] then
+ return ps_error('rangecheck')
+ end
+ if ta == 'array' then
+ local newarr = get_VM(vc)
+ local oldarr = get_VM(va)
+ local index = 1
+ local lastindex = c[6]
+ local step = a[5]
+ while index <= lastindex do
+ if oldarr[vb+index][1] == 'null' then
+ a[5] = a[5] + 1 -- needs checking, a[5] not used
+ -- step = step + 1
+ end
+ oldarr[vb+index] = newarr[index]
+ index = index + 1
+ end
+ else
+ local thestring = get_VM(va)
+ VM[va] = sub(thestring,1,vb) .. get_VM(vc) .. sub(thestring,vb+c[6]+1)
+ end
+ return true
+end
+
+function operators.aload()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ if ta ~= "array" then
+ return ps_error('typecheck')
+ end
+ if aa == "execute-only" or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local array = get_VM(va)
+ for i=1,#array do
+ push_opstack(array[i])
+ end
+ push_opstack(a)
+ return true
+end
+
+function operators.astore()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ if ta ~= "array" then
+ return ps_error('typecheck')
+ end
+ if aa == "execute-only" or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local array = get_VM(va)
+ local count = a[6]
+ for i=1,count do
+ local v = pop_opstack()
+ if not v then
+ return ps_error('stackunderflow')
+ end
+ array[i] = v
+ end
+ a[5] = a[5] + count
+ push_opstack(a)
+ return true
+end
+
+function operators.forall()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ local tb, ab, vb = b[1], b[2], b[4]
+ if not tb == "array" and b[3] == 'executable' then
+ return ps_error('typecheck')
+ end
+ if tb == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ if not (ta == "array" or ta == 'dict' or ta == 'string' or ta == "font") then
+ return ps_error('typecheck')
+ end
+ if aa == "execute-only" or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ push_execstack { '.exit', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ if ta == 'array' then
+ if a[6] == 0 then
+ return true
+ end
+ b[7] = 'i'
+ local thearray = get_VM(va)
+ for i=1,#thearray do
+ if stopped then
+ stopped = false
+ return false
+ end
+ push_opstack(thearray[i])
+ b[5] = 1
+ push_execstack(b)
+ while curstack <= execstackptr do
+ do_exec()
+ end
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and antry[4] == true then
+ pop_execstack()
+ return true
+ end
+ elseif ta == 'dict' or ta == 'font' then
+ local thedict = get_VM(va)
+ if thedict.size == 0 then
+ return true
+ end
+ b[7] = 'i'
+ local thedict = get_VM(va)
+ for k, v in next, thedict.dict do
+ if stopped then
+ stopped = false
+ return false
+ end
+ if type(k) == "string" then
+ push_opstack { 'name', 'unlimited', 'literal', add_VM(k) }
+ else
+ push_opstack(k)
+ end
+ push_opstack(v)
+ b[5] = 1
+ push_execstack(b)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and antry[4] == true then
+ pop_execstack()
+ return true
+ end
+ end
+ else -- string
+ if a[6] == 0 then
+ return true
+ end
+ b[7] = 'i'
+ local thestring = get_VM(va)
+ for v in gmatch(thestring,".") do -- we can use string.bytes
+ if stopped then
+ stopped = false
+ return false
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', byte(v) }
+ b[5] = 1
+ push_execstack(b)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and antry[4] == true then
+ pop_execstack()
+ return true;
+ end
+ end
+ end
+ return true
+end
+
+-- Dictionary operators
+--
+-- +dict ^length +maxlength +begin +end +def +load +store ^get ^put +known +where ^copy
+-- ^forall ^errordict ^systemdict ^userdict +currentdict +countdictstack +dictstack
+
+function operators.dict()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not a[1] == 'integer' then
+ return ps_error('typecheck')
+ end
+ local s = a[4]
+ if s < 0 then
+ return ps_error('rangecheck')
+ end
+ if s == 0 then -- level 2 feature
+ s = MAX_INT
+ end
+ push_opstack {
+ 'dict',
+ 'unlimited',
+ 'literal',
+ add_VM {
+ access = 'unlimited',
+ size = 0,
+ maxsize = s,
+ dict = { },
+ }
+ }
+end
+
+function operators.maxlength()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ if ta ~= 'dict' then
+ return ps_error('typecheck')
+ end
+ if aa == 'execute-only' or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local thedict = get_VM(va)
+ push_opstack { 'integer', 'unlimited', 'literal', thedict.maxsize }
+end
+
+function operators.begin()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'dict' then
+ return ps_error('typecheck')
+ end
+ dictstackptr = dictstackptr + 1
+ dictstack[dictstackptr] = a[4]
+end
+
+operators["end"] = function()
+ if dictstackptr < 3 then
+ return ps_error('dictstackunderflow')
+ end
+ dictstack[dictstackptr] = nil
+ dictstackptr = dictstackptr - 1
+end
+
+function operators.def()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'name' and a[3] == 'literal') then
+ return ps_error('typecheck')
+ end
+ if b[1] == 'array' then
+ b[7] = 'i'
+ end
+ local thedict = get_VM(dictstack[dictstackptr])
+ if not thedict.dict[get_VM(a[4])] then
+ if thedict.size == thedict.maxsize then
+ -- return ps_error('dictfull') -- level 1 only
+ end
+ thedict.size = thedict.size + 1
+ end
+ thedict.dict[get_VM(a[4])] = b
+ return true
+end
+
+-- unclear: the book says this operator can return typecheck
+
+function operators.load()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local aa = a[2]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local v = lookup(get_VM(a[4]))
+ if not v then
+ return ps_error('undefined')
+ end
+ push_opstack(v)
+end
+
+function operators.store()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'name' and a[3] == 'literal') then
+ return ps_error('typecheck')
+ end
+ if b[7] == 'array' then
+ b[7] = 'i'
+ end
+ local val, dictloc = lookup(a[4])
+ if val then
+ local thedict = get_VM(dictstack[dictloc])
+ if thedict.access == 'execute-only' or thedict.access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ thedict.dict[a[4]] = b
+ else
+ local thedict = get_VM(dictstack[dictstackptr])
+ local access = thedict.access
+ local size = thedict.size
+ if access == 'execute-only' or access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ if size == thedict.maxsize then
+ return ps_error('dictfull')
+ end
+ thedict.size = size + 1
+ thedict.dict[a[4]] = b
+ end
+ return true
+end
+
+function operators.known()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ local tb, vb = b[1], b[4]
+ if ta ~= 'dict' then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'name' or tb == 'operator') then
+ return ps_error('typecheck')
+ end
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local thedict = get_VM(va)
+ push_opstack {'boolean', 'unlimited', 'literal', thedict.dict[vb] and true or false }
+ return true
+end
+
+function operators.where()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'name' and a[3] == 'literal') then
+ return ps_error('typecheck')
+ end
+ local val, dictloc = lookup(get_VM(a[4]))
+ local thedict = dictloc and get_VM(dictstack[dictloc]) -- fixed
+ if val then
+ if thedict.access == 'execute-only' or thedict.access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ push_opstack {'dict', 'unlimited', 'literal', dictstack[dictloc]}
+ push_opstack {'boolean', 'unlimited', 'literal', true}
+ else
+ push_opstack {'boolean', 'unlimited', 'literal', false}
+ end
+ return true
+end
+
+function operators.currentdict()
+ push_opstack { 'dict', 'unlimited', 'literal', dictstack[dictstackptr] }
+ return true
+end
+
+function operators.countdictstack()
+ push_opstack { 'integer', 'unlimited', 'literal', dictstackptr }
+ return true
+end
+
+function operators.dictstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not a[1] == 'array' then
+ return ps_error('typecheck')
+ end
+ if not a[2] == 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ if a[6] < dictstackptr then
+ return ps_error('rangecheck')
+ end
+ local thearray = get_VM(a[4])
+ local subarray = { }
+ for i=1,dictstackptr do
+ thearray[n] = { 'dict', 'unlimited', 'literal', dictstack[i] }
+ subarray[n] = thearray[i]
+ end
+ a[5] = a[5] + dictstackptr
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(subarray), dictstackptr, dictstackptr, '' }
+ return true
+end
+
+-- String operators
+--
+-- +string ^length ^get ^put ^getinterval ^putinterval ^copy ^forall +anchorsearch +search
+-- +token
+
+function operators.string()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, va = a[1], a[4]
+ if ta ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if va < 0 then
+ return ps_error('rangecheck')
+ end
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(''), 1, va }
+end
+
+function operators.anchorsearch()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ local tb, ab, vb = b[1], b[2], b[4]
+ if not ta ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if tb ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local thestring = get_VM(va)
+ local thesearch = get_VM(vb)
+ local prefix = sub(thestring,1,#thesearch)
+ if prefix == thesearch then
+ if aa == 'read-only' then
+ return ps_error('invalidaccess')
+ end
+ local post = sub(thestring,#thesearch+1)
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(post), 1, #post }
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(prefix), 1, #prefix }
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ else
+ push_opstack(a)
+ push_opstack { 'boolean', 'unlimited', 'literal', false }
+ end
+ return true
+end
+
+function operators.search()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ local tb, ab, vb = b[1], b[2], b[4]
+ if not ta ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if tb ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local thestring = get_VM(a[4])
+ local thesearch = get_VM(b[4])
+ -- hm, can't this be done easier?
+ local n = 1
+ local match
+ while n + #thesearch-1 <= #thestring do
+ match = sub(thestring,n,n+#thesearch-1)
+ if match == thesearch then
+ break
+ end
+ n = n + 1
+ end
+ if match == thesearch then
+ if aa == 'read-only' then
+ return ps_error('invalidaccess')
+ end
+ local prefix = sub(thestring,1,n-1)
+ local post = sub(thestring,#thesearch+n)
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(post), 1, #post }
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(thesearch), 1, #thesearch }
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(prefix), 1, #prefix }
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ else
+ push_opstack(a)
+ push_opstack { 'boolean', 'unlimited', 'literal', false }
+ end
+ return true
+end
+
+function operators.token()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa, va = a[1], a[2], a[4]
+ if not (ta == 'string' or ta == 'file') then
+ return ps_error('typecheck')
+ end
+ if aa ~= 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ -- some fiddling with the tokenization process is needed
+ if ta == 'string' then
+ local top = execstackptr
+ push_execstack { '.token', 'unlimited', 'literal', false }
+ push_execstack { a[1], a[2], 'executable', va, 1, a[6] }
+ local v, err = next_object()
+ if not v then
+ pop_execstack()
+ pop_execstack()
+ push_opstack { 'boolean', 'unlimited', 'literal', false }
+ else
+ local q = pop_execstack()
+ if execstack[execstackptr][1] == '.token' then
+ pop_execstack()
+ end
+ local tq, vq = q[1], q[4]
+ if tq == 'string' and vq ~= va then
+ push_execstack(q)
+ end
+ local thestring, substring
+ if vq ~= va then
+ thestring = ""
+ substring = ""
+ else
+ thestring = get_VM(vq)
+ substring = sub(thestring,q[5] or 0)
+ end
+ push_opstack { ta, aa, a[3], add_VM(substring), 1, #substring}
+ push_opstack(v)
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ end
+ else -- file
+ if a[7] ~= 'r' then
+ return ps_error('invalidaccess')
+ end
+ push_execstack { '.token', 'unlimited', 'literal', false }
+ push_execstack { 'file', 'unlimited', 'executable', va, a[5], a[6], a[7], a[8] }
+ local v, err = next_object()
+ if not v then
+ pop_execstack()
+ pop_execstack()
+ push_opstack { 'boolean', 'unlimited', 'literal', false }
+ else
+ local q = pop_execstack() -- the file
+ a[5] = q[5]
+ if execstack[execstackptr][1] == '.token' then
+ pop_execstack()
+ end
+ push_opstack(v)
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ end
+ end
+ return true
+end
+
+-- Relational, boolean and bitwise operators
+--
+-- +eq +ne +ge +gt +le +lt +and +not +or +xor ^true ^false +bitshift
+
+local function both()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa = a[1], a[2]
+ local tb, ab = b[1], b[2]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if (ta == 'dict' and tb == 'dict') or (ta == 'array' and tb =='array') then
+ return true, a[4], b[4]
+ elseif ((ta == 'string' or ta == 'name') and (tb == 'string' or tb == 'name' )) then
+ local astr = get_VM(a[4])
+ local bstr = get_VM(b[4])
+ return true, astr, bstr
+ elseif ((ta == 'integer' or ta == 'real') and (tb == 'integer' or tb == 'real')) or (ta == tb) then
+ return true, a[4], b[4]
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.eq()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a == b }
+ return true
+ else
+ return a
+ end
+end
+
+function operators.ne()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a ~= b }
+ return true
+ else
+ return a
+ end
+end
+
+local function both()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local aa, ab = a[2], b[2]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local ta, tb = a[1], b[1]
+ local va, vb = a[4], b[4]
+ if (ta == 'real' or ta == 'integer') and (tb == 'real' or tb == 'integer') then
+ return true, va, vb
+ elseif ta == 'string' and tb == 'string' then
+ local va = get_VM(va)
+ local vb = get_VM(vb)
+ return true, va, vb
+ else
+ return ps_error('typecheck')
+ end
+end
+
+function operators.ge()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a >= b }
+ return true
+ else
+ return a
+ end
+end
+
+function operators.gt()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a > b }
+ return true
+ else
+ return a
+ end
+end
+
+function operators.le()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a <= b }
+ return true
+ else
+ return a
+ end
+end
+
+function operators.lt()
+ local ok, a, b = both()
+ if ok then
+ push_opstack { 'boolean', 'unlimited', 'literal', a < b }
+ return true
+ else
+ return a
+ end
+end
+
+local function both()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local aa, ab = a[2], b[2]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ local ta, tb = a[1], b[1]
+ local va, vb = a[4], b[4]
+ if ta == 'boolean' and tb == 'boolean' then
+ return ta, va, vb
+ elseif ta == 'integer' and tb == 'integer' then
+ return ta, va, vb
+ else
+ return ps_error('typecheck')
+ end
+end
+
+operators["and"]= function()
+ local ok, a, b = both()
+ if ok == 'boolean' then
+ push_opstack { 'boolean', 'unlimited', 'literal', a[1] and b[1] }
+ return true
+ elseif ok == 'integer' then
+ push_opstack { 'integer', 'unlimited', 'literal', bitand(a[1],b[1]) }
+ return true
+ else
+ return a
+ end
+end
+
+operators["or"] = function()
+ local ok, a, b = both()
+ if ok == 'boolean' then
+ push_opstack {'boolean', 'unlimited', 'literal', a[1] or b[1] }
+ return true
+ elseif ok == 'integer' then
+ push_opstack {'integer', 'unlimited', 'literal', bitor(a[1],b[1]) }
+ return true
+ else
+ return a
+ end
+end
+
+function operators.xor()
+ local ok, a, b = both()
+ if ok == 'boolean' then
+ push_opstack {'boolean', 'unlimited', 'literal', a[1] ~= b[1] }
+ return true
+ elseif ok == 'integer' then
+ push_opstack {'integer', 'unlimited', 'literal', bitxor(a[1],b[1]) }
+ return true
+ else
+ return a
+ end
+end
+
+operators["not"] = function()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local aa = a[2]
+ local ta = a[1]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ta == 'boolean' then
+ push_opstack { 'boolean', 'unlimited', 'literal', not a[4] }
+ elseif ta == 'integer' then
+ push_opstack { 'integer', 'unlimited', 'literal', -a[4] - 1 }
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.bitshift()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local aa, ab = a[2], b[2]
+ local ta, tb = a[1], b[1]
+ local va, vb = a[4], b[4]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if ab == 'noaccess' or ab == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ if not (ta == 'integer' and tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', bitrshift(va,vb < 0 and -vb or vb) }
+ return true
+end
+
+-- Control operators
+--
+-- +exec +if +ifelse +for +repeat +loop +exit +stop +stopped +countexecstack +execstack
+-- +quit +start
+
+function operators.exec()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] == 'array' then
+ a[7] = 'i'
+ a[5] = 1
+ end
+ push_execstack(a)
+ return true
+end
+
+operators["if"] = function()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'boolean' then
+ return ps_error('typecheck')
+ end
+ if b[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if a[4] == true then
+ b[7] = 'i'
+ b[5] = 1
+ push_execstack(b)
+ end
+ return true
+end
+
+function operators.ifelse()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'boolean' then
+ return ps_error('typecheck')
+ end
+ if b[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if c[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if a[4] == true then
+ b[5] = 1
+ b[7] = 'i'
+ push_execstack(b)
+ else
+ c[5] = 1
+ c[7] = 'i'
+ push_execstack(c)
+ end
+ return true
+end
+
+operators["for"] = function()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ local ta, tb, tc, td = a[1], b[1], c[1], d[1]
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (ta == 'integer' or ta == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'integer' or tb == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (tc == 'integer' or tc == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (td == 'array' and d[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ local initial = a[4]
+ local increment = b[4]
+ local limit = c[4]
+ if initial == limit then
+ return true
+ end
+ push_execstack { '.exit', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ local tokentype = (a[1] == 'real' or b[1] == 'real' or c[1] == 'real') and 'real' or 'integer'
+ d[7] = 'i'
+ local first, last
+ if increment >= 0 then
+ first, last = initial, limit
+ else
+ first, last = limit, limit
+ end
+ for control=first,last,increment do
+ if stopped then
+ stopped = false
+ return false
+ end
+ push_opstack { tokentype, 'unlimited', 'literal', control }
+ d[5] = 1
+ push_execstack(d)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and entry[4] == true then
+ pop_execstack()
+ return true;
+ end
+ end
+ return true
+end
+
+operators["repeat"] = function()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if a[4] < 0 then
+ return ps_error('rangecheck')
+ end
+ if not (b[1] == 'array' and b[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ local limit = a[4]
+ if limit == 0 then
+ return true
+ end
+ push_execstack { '.exit', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ b[7] = 'i'
+ local control = 0
+ while control < limit do
+ if stopped then
+ stopped = false
+ return false
+ end
+ b[5] = 1
+ push_execstack(b)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and entry[4] == true then
+ pop_execstack()
+ return true;
+ end
+ control = control + 1
+ end
+ return true
+end
+
+function operators.loop()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'array' and a[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ push_execstack { '.exit', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ a[7] = 'i'
+ while true do
+ if stopped then
+ stopped = false
+ return false
+ end
+ a[5] = 1
+ push_execstack(a)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ if execstackptr > 0 then
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and entry[4] == true then
+ pop_execstack()
+ return true
+ end
+ end
+ end
+ return true
+end
+
+function operators.exit()
+ local v = pop_execstack()
+ while v do
+ local tv = val[1]
+ if tv == '.exit' then
+ push_execstack { '.exit', 'unlimited', 'literal', true }
+ return true
+ elseif tv == '.stopped' or tv == '.run' then
+ push_execstack(v)
+ return ps_error('invalidexit')
+ end
+ v = pop_execstack()
+ end
+ report("exit without context, quitting")
+ push_execstack { 'operator', 'unlimited', 'executable', operators.quit, "quit" }
+ return true
+end
+
+function operators.stop()
+ local v = pop_execstack()
+ while v do
+ if val[1] == '.stopped' then
+ stopped = true
+ push_opstack { 'boolean', 'unlimited', 'executable', true }
+ return true
+ end
+ v = pop_execstack()
+ end
+ report("stop without context, quitting")
+ push_execstack { 'operator', 'unlimited', 'executable', operators.quit, "quit" }
+ return true
+end
+
+function operators.stopped()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ -- push a special token on the exec stack (handled by next_object):
+ push_execstack { '.stopped', 'unlimited', 'literal', false }
+ a[3] = 'executable'
+ if a[1] == 'array' then
+ a[7] = 'i'
+ a[5] = 1
+ end
+ push_execstack(a)
+ return true
+end
+
+function operators.countexecstack()
+ push_opstack { 'integer', 'unlimited', 'literal', execstackptr }
+ return true
+end
+
+function operators.execstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not a[1] == 'array' then
+ return ps_error('typecheck')
+ end
+ if not a[2] == 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ if a[6] < execstackptr then
+ return ps_error('rangecheck')
+ end
+ local thearray = get_VM(a[4])
+ local subarray = { }
+ for n=1,execstackptr do
+ -- thearray[n] = execstack[n]
+ -- subarray[n] = thearray[n]
+ local v = execstack[n]
+ thearray[n] = v
+ subarray[n] = v
+ a[5] = a[5] + 1
+ end
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(subarray), execstackptr, execstackptr, "" }
+ return true
+end
+
+-- clearing the execstack does the trick,
+-- todo: leave open files to be handled by the lua interpreter, for now
+
+function operators.quit()
+ while execstackptr >= 0 do -- todo: for loop / slot 0?
+ execstack[execstackptr] = nil
+ execstackptr = execstackptr - 1
+ end
+ return true
+end
+
+-- does nothing, for now
+
+function operators.start()
+ return true
+end
+
+-- Type, attribute and conversion operators
+--
+-- +type +cvlit +cvx +xcheck +executeonly +noaccess +readonly +rcheck +wcheck +cvi
+-- +cvn +cvr +cvrs +cvs
+
+function operators.type()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ push_opstack { "name", "unlimited", "executable", add_VM(a[1] .. "type") }
+ return true
+end
+
+function operators.cvlit() -- no need to push/pop
+ local a = get_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ a[3] = 'literal'
+ return true
+end
+
+function operators.cvx()
+ local a = get_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ a[3] = 'executable'
+ return true
+end
+
+function operators.xcheck()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ push_opstack { 'boolean', 'unlimited', 'literal', a[3] == 'executable' }
+ return true
+end
+
+function operators.executeonly()
+ local a = pop_opstack() -- get no push
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'string' or ta == 'file' or ta == 'array' then
+ if a[2] == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ a[2] = 'execute-only'
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack(a)
+ return true
+end
+
+function operators.noaccess()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'string' or ta == 'file' or ta == 'array' then
+ if a[2] == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ a[2] = 'noaccess'
+ elseif ta == "dict" then
+ local thedict = get_VM(a[4])
+ if thedict.access == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ thedict.access = 'noaccess'
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack(a)
+ return true
+end
+
+function operators.readonly()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'string' or ta == 'file' or ta == 'array' then
+ local aa = a[2]
+ if aa == 'noaccess' or aa == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ a[2] = 'read-only'
+ elseif ta == 'dict' then
+ local thedict = get_VM(a[4])
+ local access = thedict.access
+ if access == 'noaccess' or access == 'execute-only' then
+ return ps_error('invalidaccess')
+ end
+ thedict.access = 'read-only'
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack(a)
+ return true
+end
+
+function operators.rcheck()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ local aa
+ if ta == 'string' or ta == 'file' or ta == 'array' then
+ aa = a[2]
+ elseif ta == 'dict' then
+ aa = get_VM(a[4]).access
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack { 'boolean', 'unlimited', 'literal', aa == 'unlimited' or aa == 'read-only' }
+ return true
+end
+
+function operators.wcheck()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ local aa
+ if ta == 'string' or ta == 'file' or ta == 'array' then
+ aa = a[2]
+ elseif ta == 'dict' then
+ local thedict = get_VM(a[4])
+ aa = thedict.access
+ else
+ return ps_error('typecheck')
+ end
+ push_opstack { 'boolean', 'unlimited', 'literal', aa == 'unlimited' }
+ return true
+end
+
+function operators.cvi()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'string' then
+ push_opstack(a)
+ local ret, err = operators.token()
+ if not ret then
+ return ret, err
+ end
+ local b = pop_opstack()
+ if b[4] == false then
+ return ps_error('syntaxerror')
+ end
+ a = pop_opstack()
+ pop_opstack() -- get rid of the postmatch string remains
+ ta = a[1]
+ end
+ local aa = a[2]
+ if not (aa == 'unlimited' or aa == 'read-only') then
+ return ps_error('invalidaccess')
+ end
+ if ta == 'integer' then
+ push_opstack(a)
+ elseif ta == 'real' then
+ local va = a[4]
+ local c = va < 0 and -floor(-va) or floor(ava)
+ if abs(c) > MAX_INT then
+ return ps_error('rangecheck')
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', c }
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.cvn()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, aa = a[1], a[2]
+ local ta = a[1]
+ if ta ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if aa == 'execute-only' or aa == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ push_opstack { 'name', aa, a[3], add_VM(get_VM(a[4])) }
+ return true
+end
+
+function operators.cvr()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'string' then
+ push_opstack(a)
+ local ret, err = operators.token()
+ if not ret then
+ return ret, err
+ end
+ local b = pop_opstack()
+ if b[4] == false then
+ return ps_error('syntaxerror')
+ end
+ a = pop_opstack()
+ pop_opstack() -- get rid of the postmatch string remains
+ ta = a[1]
+ end
+ local aa = a[2]
+ if not (aa == 'unlimited' or aa == 'read-only') then
+ return ps_error('invalidaccess')
+ end
+ if ta == 'integer' then
+ push_opstack { 'real', 'unlimited', 'literal', a[4] }
+ elseif ta == 'real' then
+ push_opstack(a)
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+do
+
+ local byte0 = byte('0')
+ local byteA = byte('A') - 10
+
+ function operators.cvrs()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc = a[1], b[1], c[1]
+ if not (ta == 'integer' or ta == 'real') then
+ return ps_error('typecheck')
+ end
+ if not tb == 'integer' then
+ return ps_error('typecheck')
+ end
+ if not tc == 'string' then
+ return ps_error('typecheck')
+ end
+ if not c[2] == 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ local va, vb, vc = a[4], b[4], c[4]
+ if (vb < 2 or vb > 36) then
+ return ps_error('rangecheck')
+ end
+ if ta == 'real' then
+ push_opstack(a)
+ local ret, err = operators.cvi()
+ if ret then
+ return ret, err
+ end
+ a = pop_opstack()
+ end
+ -- todo: use an lpeg
+ local decimal = va
+ local str = { }
+ local n = 0
+ while decimal > 0 do
+ local digit = decimal % vb
+ n = n + 1
+ str[n] = digit < 10 and char(digit+byte0) or char(digit+byteA)
+ decimal = floor(decimal/vb)
+ end
+ if n > c[6] then
+ return ps_error('rangecheck')
+ end
+ str = concat(reverse(str))
+ local thestring = get_VM(vc)
+ VM[va] = str .. sub(thestring,n+1,-1)
+ push_opstack { c[1], c[2], c[3], add_VM(repl), n, n }
+ return true
+ end
+
+end
+
+function operators.cvs()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not 4 then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ local ab = b[2]
+ if not tb == 'string' then
+ return ps_error('typecheck')
+ end
+ if not ab == 'unlimited' then
+ return ps_error('invalidaccess')
+ end
+ local va, vb = a[4], b[4]
+ if ta == 'real' then
+ if floor(va) == va then
+ va = tostring(va) .. '.0'
+ else
+ va = tostring(va)
+ end
+ elseif ta == 'integer' then
+ va = tostring(va)
+ elseif ta == 'string' or ta == 'name' then
+ va = get_VM(va)
+ elseif ta == 'operator' then
+ va = a[5]
+ elseif ta == 'boolean' then
+ va = tostring(va)
+ else
+ va = "--nostringval--"
+ end
+ local n = #va
+ if n > b[6] then
+ return ps_error('rangecheck')
+ end
+ local thestring = get_VM(vb)
+ VM[vb] = va .. sub(thestring,n+1,-1)
+ push_opstack { tb, ab, b[3], add_VM(va), n, n }
+ return true
+end
+
+-- File operators
+--
+-- +file +closefile +read +write +writestring +readhexstring +writehexstring +readline ^token
+-- +bytesavailable +flush +flushfile +resetfile +status +run +currentfile +print ^= ^stack
+-- +== ^pstack ^prompt +echo
+
+function operators.file()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if a[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ local fmode = get_VM(b[4])
+ local fname = get_VM(a[4])
+ -- only accept (r), (w) and (a)
+ if fmode ~= "r" and fmode ~= "w" and fmode ~= "a" then
+ return ps_error('typecheck')
+ end
+ if fname == "%stdin" then
+ -- can only read from stdin
+ if fmode ~= "r" then
+ return ps_error('invalidfileaccess')
+ end
+ push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stdin }
+ elseif fname == "%stdout" then
+ -- can't read from stdout i.e. can only append, in fact, but lets ignore that
+ if fmode == "r" then
+ return ps_error('invalidfileaccess')
+ end
+ push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stdout }
+ elseif fname == "%stderr" then
+ -- cant read from stderr i.e. can only append, in fact, but lets ignore that
+ if fmode == "r" then
+ return ps_error('invalidfileaccess')
+ end
+ push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, io.stderr }
+ elseif fname == "%statementedit" or fname == "%lineedit"then
+ return ps_error('invalidfileaccess')
+ else
+ -- so it is a normal file
+ local myfile, error = io.open(fname,fmode)
+ if not myfile then
+ return ps_error('undefinedfilename')
+ end
+ if fmode == 'r' then
+ l = myfile:read("*a")
+ if not l then
+ return ps_error('invalidfileaccess')
+ end
+ -- myfile:close() -- do not close here, easier later on
+ push_opstack { 'file', 'unlimited', 'literal', add_VM(l), 1, #l, fmode, myfile}
+ else
+ push_opstack { 'file', 'unlimited', 'literal', 0, 0, 0, fmode, myfile}
+ end
+ end
+ return true
+end
+
+function operators.read()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] ~= 'r' then
+ return ps_error('invalidaccess')
+ end
+ local b
+ local v = a[4]
+ local f = a[8]
+ if v > 0 then
+ local thestr = get_VM(v)
+ local n = a[5]
+ if n < a[6] then
+ byte = sub(thestr,n,n+1)
+ -- a[5] = n + 1
+ end
+ else -- %stdin
+ b = f:read(1)
+ end
+ if b then
+ push_opstack { 'integer', 'unlimited', 'literal', byte(b) }
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ else
+ f:close()
+ push_opstack { 'boolean', 'unlimited', 'literal', false}
+ end
+ return true
+end
+
+function operators.write()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] == 'r' then
+ return ps_error('ioerror')
+ end
+ a[8]:write(char(b[4] % 256))
+ return true
+end
+
+function operators.writestring()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] == 'r' then
+ return ps_error('ioerror')
+ end
+ a[8]:write(get_VM(b[4]))
+ return true
+end
+
+function operators.writehexstring()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] == 'r' then
+ return ps_error('ioerror')
+ end
+ local f = a[8]
+ local s = get_VM(b[4])
+ for w in gmatch(s,".") do
+ f:write(format("%x",byte(w))) -- we have a table for that somewhere
+ end
+ return true
+end
+
+do
+
+ local function get_string_line(a)
+ local str = get_VM(a[4])
+ local start = a[5]
+ local theend = a[6]
+ if start == theend then
+ return nil
+ end
+ str = match(str,"[\n\r]*([^\n\r]*)",start)
+ a[5] = a[5] + #str + 1 -- ?
+ return str
+ end
+
+ local function get_hexstring_line (a,b)
+ local thestring = get_VM(a[4])
+ local start, theend = a[5], a[6]
+ if start == theend then
+ return nil
+ end
+ local prefix, result, n = nil, { }, 0
+ local nmax = b[6]
+ while start < theend do
+ local b = sub(thestring,start,start)
+ if not b then
+ break
+ end
+ local hexbyte = tonumber(b,16)
+ if not hexbyte then
+ -- skip
+ elseif prefix then
+ n = n + 1
+ result[n] = char(prefix*16+hexbyte)
+ if n == nmax then
+ break
+ else
+ prefix = nil
+ end
+ else
+ prefix = hexbyte
+ end
+ start = start + 1
+ end
+ a[5] = start + 1 -- ?
+ return concat(result)
+ end
+
+ function operators.readline()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] ~= 'r' then
+ return ps_error('invalidaccess')
+ end
+ local va = a[4]
+ if va > 0 then
+ va = get_string_line(a)
+ else
+ va = a[8]:read('*l')
+ end
+ if not va then
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(''), 0, 0 }
+ push_opstack { 'boolean', 'unlimited', 'literal', false }
+ else
+ local n = #va
+ if n > b[6] then
+ return ps_error('rangecheck')
+ end
+ local thestring = get_VM(b[4])
+ VM[b[4]] = va .. sub(thestring,#va+1, -1)
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(va), n, n }
+ push_opstack { 'boolean', 'unlimited', 'literal', true }
+ end
+ return true
+ end
+
+ function operators.readhexstring()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if not (ta == 'string' or ta == 'file') then
+ return ps_error('typecheck')
+ end
+ local thefile = a[8]
+ local va = a[4]
+ if va > 0 then
+ va = get_hexstring_line (a,b)
+ else
+ local prefix, result, n = nil, { }, 0
+ -- todo: read #va bytes and lpeg
+ while true do
+ local b = thefile:read(1)
+ if not b then
+ break
+ end
+ local hexbyte = tonumber(b,16)
+ local nmax = b[6]
+ if not hexbyte then
+ -- skip
+ elseif prefix then
+ n = n + 1
+ result[n] = char(prefix*16+hexbyte)
+ if n == nmax then
+ break
+ else
+ prefix = nil
+ end
+ else
+ prefix = hexbyte
+ end
+ end
+ va = concat(result)
+ end
+ local thestring = get_VM(b[4])
+ local n = #va
+ VM[b[4]] = repl .. sub(thestring,n+1,-1)
+ push_opstack { b[1], b[2], b[3], add_VM(va), n, n }
+ push_opstack { 'boolean', 'unlimited', 'literal', n == b[6] }
+ return true
+ end
+
+end
+
+function operators.flush()
+ io.flush()
+ return true
+end
+
+function operators.bytesavailable()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] ~= 'r' then
+ return ps_error('typecheck')
+ end
+ local waiting = (a[4] > 0) and (a[6] - a[5] + 1) or -1
+ push_opstack { "integer", "unlimited", "literal", waiting }
+ return true
+end
+
+-- this does not really do anything useful
+
+function operators.resetfile()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.flushfile()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[4] > 0 then
+ a[5] = a[6]
+ else
+ a[8]:flush()
+ end
+ return true
+end
+
+function operators.closefile()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ if a[7] == 'r' then
+ a[5] = a[6]
+ else
+ push_opstack(a)
+ operators.flushfile()
+ end
+ a[8]:close()
+ return true
+end
+
+function operators.status()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'file' then
+ return ps_error('typecheck')
+ end
+ local state = io.type(a[8])
+ push_opstack { "boolean", 'unlimited', 'literal', not state or state == "closed file" }
+ return true
+end
+
+function operators.run()
+ push_opstack { "string", "unlimited", "literal", add_VM("r"), 1, 1 }
+ local ret, err = operators.file()
+ if not ret then
+ return ret, err
+ end
+ ret, err = operators.cvx()
+ if not ret then
+ return ret, err
+ end
+ local a = pop_opstack() -- an executable file
+ push_execstack { ".run", "unlimited", "literal", false } -- constant
+ local curstack = execstackptr
+ local thefile = a[8]
+ push_execstack(a)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local state = io.type(thefile)
+ if not state or state == "closed file" then
+ -- okay
+ else
+ thefile:close()
+ end
+ if execstackptr > 0 then
+ local entry = execstack[execstackptr]
+ if entry[1] == '.run' and entry[4] == true then
+ pop_execstack()
+ end
+ end
+ return true
+end
+
+function operators.currentfile()
+ local n = execstackptr
+ while n >= 0 do
+ local entry = execstack[n]
+ if entry[1] == 'file' and entry[7] == 'r' then
+ push_opstack(entry)
+ return true
+ end
+ n = n - 1
+ end
+ push_opstack { 'file', 'unlimited', 'executable', add_VM(''), 0, 0, 'r', stdin }
+ return true
+end
+
+function operators.print()
+ local a = pop_opstack()
+ if not a then return
+ ps_error('stackunderflow')
+ end
+ if a[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ report(get_VM(a[4]))
+end
+
+-- '=' is also defined as a procedure below;
+--
+-- it is actually supposed to do this: "equaldict begin dup type exec end"
+-- where each of the entries in equaldict handles one type only, but this
+-- works just as well
+
+do
+
+ local pattern = Cs(
+ Cc("(")
+ * (
+ P("\n") / "\\n"
+ + P("\r") / "\\r"
+ + P("(") / "\\("
+ + P(")") / "\\)"
+ + P("\\") / "\\\\"
+ + P("\b") / "\\b"
+ + P("\t") / "\\t"
+ + P("\f") / "\\f"
+ + R("\000\032","\127\255") / tonumber / formatters["\\%03o"]
+ + P(1)
+ )^0
+ * Cc(")")
+ )
+
+ -- print(lpegmatch(pattern,[[h(a\nn)s]]))
+
+ local function do_operator_equal(a)
+ local ta, va = a[1], a[4]
+ if ta == 'real' then
+ if floor(va) == va then
+ return tostring(va .. '.0')
+ else
+ return tostring(va)
+ end
+ elseif ta == 'integer' then
+ return tostring(va)
+ elseif ta == 'string' then
+ return lpegmatch(pattern,get_VM(va))
+ elseif ta == 'boolean' then
+ return tostring(va)
+ elseif ta == 'operator' then
+ return '--' .. a[5] .. '--'
+ elseif ta == 'name' then
+ if a[3] == 'literal' then
+ return '/' .. get_VM(va)
+ else
+ return get_VM(va)
+ end
+ elseif ta == 'array' then
+ va = get_VM(va)
+ local isexec = a[3] == 'executable'
+ local result = { isexec and "{" or "[" }
+ local n = 1
+ for i=1,#va do
+ n = n + 1
+ result[n] = do_operator_equal(va[i])
+ end
+ result[n+1] = isexec and "}" or "]"
+ return concat(result," ")
+ elseif ta == 'null' then
+ return 'null'
+ elseif ta == 'dict' then
+ return '-dicttype-'
+ elseif ta == 'save' then
+ return '-savetype-'
+ elseif ta == 'mark' then
+ return '-marktype-'
+ elseif ta == 'file' then
+ return '-filetype-'
+ elseif ta == 'font' then
+ return '-fonttype-'
+ end
+ end
+
+ function operators.equal()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ report(do_operator_equal(a))
+ return true
+ end
+
+end
+
+local function commonstack(seperator)
+ for n=1,opstackptr do
+ push_opstack { 'string', 'unlimited', 'literal', add_VM(seperator), 1 ,1 }
+ push_opstack(opstack[n])
+ push_execstack { 'operator','unlimited','executable', operators.print, 'print'}
+ push_execstack { 'operator','unlimited','executable', operators.equal, '=='}
+ end
+ return true
+end
+
+function operators.pstack()
+ return commonstack("\n")
+end
+
+function operators.stack()
+ return commonstack(" ")
+end
+
+-- this does not really do anything useful
+
+function operators.echo()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'boolean' then
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+-- Virtual memory operators
+--
+-- +save +restore +vmstatus
+
+-- to be checked: we do a one-level shallow copy now, not sure if that
+-- is good enough yet
+
+local savelevel = 0
+
+initializers[#initializers+1] = function(reset)
+ savelevel = 0
+end
+
+function operators.save()
+ local saved_VM = { }
+ for k1, v1 in next, VM do
+ if type(v1) == "table" then
+ local t1 = { }
+ saved_VM[k1] = t1
+ for k2, v2 in next, t1 do
+ if type(v2) == "table" then
+ local t2 = { }
+ t1[k2] = t2
+ for k3, v3 in next, v2 do
+ t2[k3] = v3
+ end
+ else
+ t1[k2] = v2
+ end
+ end
+ else
+ saved_VM[k1] = v1
+ end
+ end
+ push_gsstack { 'save', copy_gsstate() }
+ savelevel = savelevel + 1
+ push_opstack { 'save', 'unlimited', 'executable', add_VM(saved_VM) }
+end
+
+do
+
+ local function validstack(stack,index,saved_VM)
+ -- loop over pstack, execstack, and dictstack to make sure
+ -- there are no entries with VM_id > #saved_VM
+ for i=index,1,-1 do
+ local v = stack[i]
+ if type(v) == "table" then
+ local tv = v[1]
+ if tv == "save" or tv == "string" or tv == "array" or tv == "dict" or tv == "name" or tv == "file" then
+ -- todo: check on %stdin/%stdout, but should be ok
+ if v[4] > #saved_VM then
+ return false
+ end
+ end
+ end
+ i = i - 1
+ end
+ return true
+ end
+
+ function operators.restore()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'save' then
+ return ps_error('typecheck')
+ end
+ if a[4] == 0 or savelevel == 0 then
+ return ps_error('invalidrestore')
+ end
+ local saved_VM = get_VM(a[4])
+ if directvm then
+ else
+ if not validstack(execstack,execstackptr,saved_VM) then
+ return ps_error('invalidrestore')
+ end
+ if not validstack(dictstack,dictstackptr,saved_VM) then
+ return ps_error('invalidrestore')
+ end
+ if not validstack(opstack,opstackptr,saved_VM) then
+ return ps_error('invalidrestore')
+ end
+ end
+ while gsstackptr > 0 do
+ local g = gsstack[gsstackptr]
+ gsstackptr = gsstackptr - 1
+ if g[1] == "save" then
+ gsstate = g[2]
+ return
+ end
+ end
+ a[4] = 0 -- invalidate save object
+ savelevel = savelevel - 1
+ VM = saved_VM
+ end
+
+end
+
+function operators.vmstatus()
+ local n = 0 -- #VM * 100
+ push_opstack { 'integer', 'unlimited', 'literal', savelevel }
+ push_opstack { 'integer', 'unlimited', 'literal', n }
+ push_opstack { 'integer', 'unlimited', 'literal', n }
+ return true
+end
+
+-- Miscellaneous operators
+--
+-- +bind +null +usertime +version
+
+-- the reference manual says bind only ERRORS on typecheck
+
+local function bind()
+ local a = pop_opstack()
+ if not a then
+ return true -- ps_error('stackunderflow')
+ end
+ if not a[1] == 'array' then
+ return ps_error('typecheck')
+ end
+ local proc = get_VM(a[4])
+ for i=1,#proc do
+ local v = proc[i]
+ local t = v[1]
+ if t == 'name' then
+ if v[3] == 'executable' then
+ local op = lookup(get_VM(v[4]))
+ if op and op[1] == 'operator' then
+ proc[i] = op
+ end
+ end
+ elseif t == 'array' then
+ if v[2] == 'unlimited' then
+ push_opstack(v)
+ bind() -- recurse
+ pop_opstack()
+ proc[i][2] = 'read-only'
+ end
+ end
+ end
+ push_opstack(a)
+end
+
+operators.bind = bind
+
+function operators.null()
+ push_opstack { 'null', 'unlimited', 'literal' }
+ return true
+end
+
+function operators.usertime()
+ push_opstack { 'integer', 'unlimited', 'literal', floor(os.clock() * 1000) }
+ return true
+end
+
+function operators.version()
+ push_opstack { 'string', 'unlimited', 'literal', add_VM('23.0') }
+ return true
+end
+
+-- Graphics state operators
+--
+-- +gsave +grestore +grestoreall +initgraphics +setlinewidth +currentlinewidth +setlinecap +currentlinecap
+-- +setlinejoin +currentlinejoin +setmiterlimit +currentmiterlimit +setdash +currentdash +setflat +currentflat
+-- +setgray +currentgray +sethsbcolor +currenthsbcolor +setrgbcolor +setcmykcolor +currentrgbcolor +setscreen
+-- +currentscreen +settransfer +currenttransfer
+
+function operators.gsave()
+ push_gsstack { 'gsave', copy_gsstate() }
+ return true
+end
+
+function operators.grestore()
+ if gsstackptr > 0 then
+ local g = gsstack[gsstackptr]
+ if g[1] == "gsave" then
+ gsstackptr = gsstackptr - 1
+ gsstate = g[2]
+ end
+ end
+ return true
+end
+
+function operators.grestoreall() -- needs checking
+ for i=gsstackptr,1,-1 do
+ local g = gsstack[i]
+ if g[1] == "save" then
+ gsstate = g[2]
+ gsstackptr = i
+ return true
+ end
+ end
+ gsstackptr = 0
+ return true
+end
+
+function operators.initgraphics()
+ local newstate = copy_gsstate() -- hm
+ newstate.matrix = { 1, 0, 0, 1, 0, 0 }
+ newstate.color = { gray = 0, hsb = { }, rgb = { }, cmyk = { }, type = "gray" }
+ newstate.position = { } -- actual x and y undefined
+ newstate.path = { }
+ newstate.linewidth = 1
+ newstate.linecap = 0
+ newstate.linejoin = 0
+ newstate.miterlimit = 10
+ newstate.dashpattern = { }
+ newstate.dashoffset = 0
+ gsstate = newstate
+ device.initgraphics()
+ operators.initclip()
+ return true
+end
+
+function operators.setlinewidth()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local t = a[1]
+ if not (t == 'integer' or t == 'real') then
+ return ps_error('typecheck')
+ end
+ gsstate.linewidth = a[4]
+ return true
+end
+
+function operators.currentlinewidth()
+ local w = gsstate.linewidth
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer',
+ 'unlimited',
+ 'literal',
+ w,
+ }
+ return true
+end
+
+function operators.setlinecap()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local c = a[4]
+ if c > 2 or c < 0 then
+ return ps_error('rangecheck')
+ end
+ gsstate.linecap = c
+ return true
+end
+
+function operators.currentlinecap()
+ push_opstack { 'integer', 'unlimited', 'literal', gsstate.linecap }
+ return true
+end
+
+function operators.setlinejoin()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'integer' then
+ return ps_error('typecheck')
+ end
+ local j = a[4]
+ if j > 2 or j < 0 then
+ return ps_error('rangecheck')
+ end
+ gsstate.linejoin = j
+ return true
+end
+
+function operators.currentlinejoin()
+ push_opstack { 'integer', 'unlimited', 'literal', gsstate.linejoin }
+ return true
+end
+
+function operators.setmiterlimit()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local t = a[1]
+ if not (t == 'integer' or t == 'real') then
+ return ps_error('typecheck')
+ end
+ local m = a[4]
+ if m < 1 then
+ return ps_error('rangecheck')
+ end
+ gsstate.miterlimit = m
+ return true
+end
+
+function operators.currentmiterlimit()
+ local w = gsstate.miterlimit
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer',
+ 'unlimited',
+ 'literal',
+ w
+ }
+ return true
+end
+
+function operators.setdash()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if ta ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'integer' or tb == 'real') then
+ return ps_error('typecheck')
+ end
+ local pattern = { }
+ local total = 0
+ local thearray = get_VM(a[4])
+ for i=1,#thearray do
+ local a = thearray[i]
+ local ta, va = a[1], a[4]
+ if ta ~= "integer" then
+ return ps_error('typecheck')
+ end
+ if va < 0 then
+ return ps_error('limitcheck')
+ end
+ total = total + va
+ pattern[#pattern+1] = va
+ end
+ if #pattern > 0 and total == 0 then
+ return ps_error('limitcheck')
+ end
+ gsstate.dashpattern = pattern
+ gsstate.dashoffset = b[4]
+ return true
+end
+
+function operators.currentdash()
+ local thearray = gsstate.dashpattern
+ local pattern = { }
+ for i=1,#thearray do
+ pattern[i] = { 'integer', 'unlimited', 'literal', thearray[i] }
+ end
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(pattern), #pattern, #pattern }
+ local w = gsstate.dashoffset
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', 'unlimited', 'literal', w
+ }
+ return true
+end
+
+function operators.setflat()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, va = a[1], a[4]
+ if not (ta == 'integer' or ta == 'real') then
+ return ps_error('typecheck')
+ end
+ gsstate.flatness = va
+ return true
+end
+
+function operators.currentflat()
+ local w = gsstate.flatness
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w) ~= w) and 'real' or 'integer', 'unlimited', 'literal', w
+ }
+ return true
+end
+
+-- Color conversion functions
+--
+-- normally, level one colors are based on hsb, but for our backend it is better to
+-- stick with the original request when possible
+
+do
+
+ local function rgb_to_gray (r, g, b)
+ return 0.30 * r + 0.59 * g + 0.11 * b
+ end
+
+ local function cmyk_to_gray (c, m, y, k)
+ return 0.30 * (1.0 - min(1.0,c+k)) + 0.59 * (1.0 - min(1.0,m+k)) + 0.11 * (1.0 - min(1.0,y+k))
+ end
+
+ local function cmyk_to_rgb (c, m, y, k)
+ return 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k)
+ end
+
+ local function rgb_to_hsv(r, g, b)
+ local offset, maximum, other_1, other_2
+ if r >= g and r >= b then
+ offset, maximum, other_1, other_2 = 0, r, g, b
+ elseif g >= r and g >= b then
+ offset, maximum, other_1, other_2 = 2, g, b, r
+ else
+ offset, maximum, other_1, other_2 = 4, b, r, g
+ end
+ if maximum == 0 then
+ return 0, 0, 0
+ end
+ local minimum = other_1 < other_2 and other_1 or other_2
+ if maximum == minimum then
+ return 0, 0, maximum
+ end
+ local delta = maximum - minimum
+ return (offset + (other_1-other_2)/delta)/6, delta/maximum, maximum
+ end
+
+ local function gray_to_hsv (col)
+ return 0, 0, col
+ end
+
+ local function gray_to_rgb (col)
+ return 1-col, 1-col, 1-col
+ end
+
+ local function gray_to_cmyk (col)
+ return 0, 0, 0, col
+ end
+
+ local function hsv_to_rgb(h,s,v)
+ local hi = floor(h * 6.0) % 6
+ local f = (h * 6) - floor(h * 6)
+ local p = v * (1 - s)
+ local q = v * (1 - f * s)
+ local t = v * (1 - (1 - f) * s)
+ if hi == 0 then
+ return v, t, p
+ elseif hi == 1 then
+ return q, v, p
+ elseif hi == 2 then
+ return p, v, t
+ elseif hi == 3 then
+ return p, q, v
+ elseif hi == 4 then
+ return t, p, v
+ elseif hi == 5 then
+ return v, p, q
+ end
+ end
+
+ local function hsv_to_gray(h,s,v)
+ return rgb_to_gray(hsv_to_rgb(h,s,v))
+ end
+
+ -- color operators
+
+ function operators.setgray()
+ local g = pop_opstack()
+ if not g then
+ return ps_error('stackunderflow')
+ end
+ local gt = g[1]
+ if not (gt == 'integer' or gt == 'real') then
+ return ps_error('typecheck')
+ end
+ local gv = g[4]
+ local color = gsstate.color
+ color.type = "gray"
+ color.gray = (gv < 0 and 0) or (gv > 1 and 1) or gv
+ return true
+ end
+
+ function operators.currentgray()
+ local color = gsstate.color
+ local t = color.type
+ local s
+ if t == "gray" then
+ s = color.gray
+ elseif t == "rgb" then
+ local col = color.rgb
+ s = rgb_to_gray(col[1],col[2],col[3])
+ elseif t == "cmyk" then
+ local col = cmyk
+ s = cmyk_to_gray(col[1],col[2],col[3],col[4])
+ else
+ local col = color.hsb
+ s = hsv_to_gray(col[1],col[2],col[3])
+ end
+ push_opstack { (s == 0 or s == 1) and 'integer' or 'real', 'unlimited', 'literal', s }
+ return true
+ end
+
+ function operators.sethsbcolor()
+ local b = pop_opstack()
+ local s = pop_opstack()
+ local h = pop_opstack()
+ if not h then
+ return ps_error('stackunderflow')
+ end
+ local ht, st, bt = h[1], s[1], b[1]
+ if not (ht == 'integer' or ht == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (st == 'integer' or st == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (bt == 'integer' or bt == 'real') then
+ return ps_error('typecheck')
+ end
+ local hv, sv, bv = h[4], s[4], b[4]
+ local color = gsstate.color
+ color.type = "hsb"
+ color.hsb = {
+ (hv < 0 and 0) or (hv > 1 and 1) or hv,
+ (sv < 0 and 0) or (sv > 1 and 1) or sv,
+ (bv < 0 and 0) or (bv > 1 and 1) or bv,
+ }
+ return true
+ end
+
+ function operators.currenthsbcolor()
+ local color = gsstate.color
+ local t = color.type
+ local h, s, b
+ if t == "gray" then
+ h, s, b = gray_to_hsv(color.gray)
+ elseif t == "rgb" then
+ local col = color.rgb
+ h, s, b = rgb_to_hsv(col[1],col[2],col[3])
+ elseif t == "cmyk" then
+ local col = color.cmyk
+ h, s, b = cmyk_to_hsv(col[1],col[2],col[3],col[4])
+ else
+ local col = color.hsb
+ h, s, b = col[1], col[2], col[3]
+ end
+ push_opstack { (h == 0 or h == 1) and 'integer' or 'real', 'unlimited', 'literal', h }
+ push_opstack { (s == 0 or s == 1) and 'integer' or 'real', 'unlimited', 'literal', s }
+ push_opstack { (b == 0 or b == 1) and 'integer' or 'real', 'unlimited', 'literal', b }
+ return true
+ end
+
+ function operators.setrgbcolor()
+ local b = pop_opstack()
+ local g = pop_opstack()
+ local r = pop_opstack()
+ if not r then
+ return ps_error('stackunderflow')
+ end
+ local rt, gt, bt = r[1], g[1], b[1]
+ if not (rt == 'integer' or rt == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (gt == 'integer' or gt == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (bt == 'integer' or bt == 'real') then
+ return ps_error('typecheck')
+ end
+ local rv, gv, bv = r[4], g[4], b[4]
+ local color = gsstate.color
+ color.type = "rgb"
+ color.rgb = {
+ (rv < 0 and 0) or (rv > 1 and 1) or rv,
+ (gv < 0 and 0) or (gv > 1 and 1) or gv,
+ (bv < 0 and 0) or (bv > 1 and 1) or bv,
+ }
+ return true
+ end
+
+ function operators.currentrgbcolor()
+ local color = gsstate.color
+ local t = color.type
+ local r, g, b
+ if t == "gray" then
+ r, g, b = gray_to_rgb(color.gray)
+ elseif t == "rgb" then
+ local col = color.rgb
+ r, g, b = col[1], col[2], col[3]
+ elseif t == "cmyk" then
+ r, g, b = cmyk_to_rgb(color.cmyk)
+ else
+ local col = color.hsb
+ r, g, b = hsv_to_rgb(col[1], col[2], col[3])
+ end
+ push_opstack { (r == 0 or r == 1) and "integer" or "real", 'unlimited', 'literal', r }
+ push_opstack { (g == 0 or g == 1) and "integer" or "real", 'unlimited', 'literal', g }
+ push_opstack { (b == 0 or b == 1) and "integer" or "real", 'unlimited', 'literal', b }
+ return true
+ end
+
+ function operators.setcmykcolor()
+ local k = pop_opstack()
+ local y = pop_opstack()
+ local m = pop_opstack()
+ local c = pop_opstack()
+ if not c then
+ return ps_error('stackunderflow')
+ end
+ local ct, mt, yt, kt = c[1], m[1], y[1], k[1]
+ if not (ct == 'integer' or ct == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (mt == 'integer' or mt == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (yt == 'integer' or yt == 'real') then
+ return ps_error('typecheck')
+ end
+ if not (kt == 'integer' or kt == 'real') then
+ return ps_error('typecheck')
+ end
+ local cv, mv, yv, kv = c[4], m[4], y[4], k[4]
+ local color = gsstate.color
+ color.type = "cmyk"
+ color.cmyk = {
+ (cv < 0 and 0) or (cv > 1 and 1) or cv,
+ (mv < 0 and 0) or (mv > 1 and 1) or mv,
+ (yv < 0 and 0) or (yv > 1 and 1) or yv,
+ (kv < 0 and 0) or (kv > 1 and 1) or kv,
+ }
+ return true
+ end
+
+ function operators.currentcmykcolor()
+ local color = gsstate.color
+ local t = color.type
+ local c, m, y, k
+ if t == "gray" then
+ c, m, y, k = gray_to_cmyk(color.gray)
+ elseif t == "rgb" then
+ c, m, y, k = rgb_to_cmyk(color.rgb)
+ elseif t == "cmyk" then
+ local col = color.cmyk
+ c, m, y, k = col[1], col[2], col[3], col[4]
+ else
+ local col = color.hsb
+ c, m, y, k = hsv_to_cmyk(col[1], col[2], col[3])
+ end
+ push_opstack { (c == 0 or c == 1) and "integer" or "real", 'unlimited', 'literal', c }
+ push_opstack { (m == 0 or m == 1) and "integer" or "real", 'unlimited', 'literal', m }
+ push_opstack { (y == 0 or y == 1) and "integer" or "real", 'unlimited', 'literal', y }
+ push_opstack { (k == 0 or k == 1) and "integer" or "real", 'unlimited', 'literal', k }
+ return true
+ end
+
+end
+
+function operators.setscreen()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc, ac = a[1], b[1], c[1], c[3]
+ if not (tc == 'array' and ac == 'executable') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ local va, vb, vc = a[4], b[4], c[4]
+ if vb < 0 or vb > 360 then
+ return ps_error('rangecheck')
+ end
+ if va < 0 then
+ return ps_error('rangecheck')
+ end
+ gsstate.screen = { va, vb, vc }
+ return true
+end
+
+function operators.currentscreen()
+ local w
+ if not gsstate.screen then
+ local popper = { 'operator', 'unlimited', 'executable', operators.pop, 'pop' }
+ push_opstack { 'integer', 'unlimited', 'literal', 1 }
+ push_opstack { 'integer', 'unlimited', 'literal', 0 }
+ push_opstack { 'array', 'unlimited', 'executable', add_VM{ popper }, 1, 1, 'd' }
+ else
+ local w1 = gsstate.screen[1]
+ local w2 = gsstate.screen[2]
+ local w3 = gsstate.screen[3]
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w1) ~= w1) and 'real' or 'integer', 'unlimited', 'literal', w1
+ }
+ push_opstack {
+ (abs(w) > MAX_INT or floor(w2) ~= w2) and 'real' or 'integer', 'unlimited', 'literal', w2
+ }
+ local thearray = get_VM(w3)
+ push_opstack { 'array', 'unlimited', 'executable', w3, 1, #thearray, 'd' } -- w3 or thearray ?
+ end
+ return true
+end
+
+function operators.settransfer()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'array' and a[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ local va = a[4]
+ if va < 0 then
+ return ps_error('rangecheck')
+ end
+ gsstate.transfer = va
+ return true
+end
+
+function operators.currenttransfer()
+ local transfer = gsstate.transfer
+ if not transfer then
+ push_opstack { 'array', 'unlimited', 'executable', add_VM{ }, 0, 0, 'd'}
+ else
+ local thearray = get_VM(transfer)
+ push_opstack { 'array', 'unlimited', 'executable', transfer, 1, #thearray, 'd' }
+ end
+ return true
+end
+
+-- Coordinate system and matrix operators
+--
+-- +matrix +initmatrix +identmatrix +defaultmatrix +currentmatrix +setmatrix +translate
+-- +scale +rotate +concat +concatmatrix +transform +dtransform +itransform +idtransform
+-- +invertmatrix
+
+-- are these changed in place or not? if not then we can share
+
+function operators.matrix()
+ local matrix = {
+ {'real', 'unlimited', 'literal', 1},
+ {'real', 'unlimited', 'literal', 0},
+ {'real', 'unlimited', 'literal', 0},
+ {'real', 'unlimited', 'literal', 1},
+ {'real', 'unlimited', 'literal', 0},
+ {'real', 'unlimited', 'literal', 0},
+ }
+ push_opstack { 'array', 'unlimited', 'literal', add_VM(matrix), 6, 6 }
+ return true
+end
+
+function operators.initmatrix()
+ gsstate.matrix = { 1, 0, 0, 1, 0, 0 }
+ return true
+end
+
+function operators.identmatrix()
+ local a = pop_opstack()
+ if not a then return
+ ps_error('stackunderflow')
+ end
+ if a[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if a[6] < 6 then
+ return ps_error('rangecheck')
+ end
+ local m = VM[a[4]] -- or can we replace the numbers
+ m[1] = { 'real', 'unlimited', 'literal', 1 }
+ m[2] = { 'real', 'unlimited', 'literal', 0 }
+ m[3] = { 'real', 'unlimited', 'literal', 0 }
+ m[4] = { 'real', 'unlimited', 'literal', 1 }
+ m[5] = { 'real', 'unlimited', 'literal', 0 }
+ m[6] = { 'real', 'unlimited', 'literal', 0 }
+ a[5] = 6
+ push_opstack(a)
+ return true
+end
+
+operators.defaultmatrix = operators.identmatrix
+
+function operators.currentmatrix()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if a[6] < 6 then
+ return ps_error('rangecheck')
+ end
+ local thearray = get_VM(a[4])
+ local matrix = gsstate.matrix
+ for i=1,6 do
+ thearray[i] = {'real', 'unlimited', 'literal', matrix[i]}
+ end
+ push_opstack { 'array', 'unlimited', 'literal', a[4], 6, 6 }
+ return true
+end
+
+function operators.setmatrix()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if a[6] ~= 6 then
+ return ps_error('rangecheck')
+ end
+ local thearray = get_VM(a[4])
+ local matrix = gsstate.matrix
+ for i=1,#thearray do
+ local a = thearray[i]
+ local ta, tv = a[1], a[4]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if i > 6 then
+ return ps_error('rangecheck')
+ end
+ matrix[i] = va
+ end
+ return true
+end
+
+local function do_transform(matrix,a,b)
+ local x = matrix[1] * a + matrix[3] * b + matrix[5]
+ local y = matrix[2] * a + matrix[4] * b + matrix[6]
+ return x, y
+end
+
+local function do_itransform(matrix,a,b)
+ local m1 = matrix[1]
+ local m4 = matrix[4]
+ if m1 == 0 or m4 == 0 then
+ return nil
+ end
+ local x = (a - matrix[5] - matrix[3] * b) / m1
+ local y = (b - matrix[6] - matrix[2] * a) / m4
+ return x, y
+end
+
+local function do_concat (a,b)
+ local a1, a2, a3, a4, a5, a6 = a[1], a[2], a[3], a[4], a[5], a[6]
+ local b1, b2, b3, b4, b5, b6 = b[1], b[2], b[3], b[4], b[5], b[6]
+ local c1 = a1 * b1 + a2 * b3
+ local c2 = a1 * b2 + a2 * b4
+ local c3 = a1 * b3 + a3 * b4
+ local c4 = a3 * b2 + a4 * b4
+ local c5 = a5 * b1 + a6 * b3 + b5
+ local c6 = a5 * b2 + a6 * b4 + b6
+ -- this is because double calculation introduces a small error
+ return {
+ abs(c1) < 1.0e-16 and 0 or c1,
+ abs(c2) < 1.0e-16 and 0 or c2,
+ abs(c3) < 1.0e-16 and 0 or c3,
+ abs(c4) < 1.0e-16 and 0 or c4,
+ abs(c5) < 1.0e-16 and 0 or c5,
+ abs(c6) < 1.0e-16 and 0 or c6,
+ }
+end
+
+local function do_inverse (a)
+ local a1, a2, a3, a4, a5, a6 = a[1], a[2], a[3], a[4], a[5], a[6]
+ local det = a1 * a4 - a3 * a2
+ if det == 0 then
+ return nil
+ end
+ local c1 = a4 / det
+ local c3 = -a3 / det
+ local c2 = -a2 / det
+ local c4 = a1 / det
+ local c5 = (a3 * a6 - a5 * a4) / det
+ local c6 = (a5 * a2 - a1 * a6) / det
+ return {
+ abs(c1) < 1.0e-16 and 0 or c1,
+ abs(c2) < 1.0e-16 and 0 or c2,
+ abs(c3) < 1.0e-16 and 0 or c3,
+ abs(c4) < 1.0e-16 and 0 or c4,
+ abs(c5) < 1.0e-16 and 0 or c5,
+ abs(c6) < 1.0e-16 and 0 or c6,
+ }
+end
+
+function operators.translate()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] == 'array' then
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local tf = a
+ local a = pop_opstack()
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ local m = VM[tf[4]]
+ local old = { m[1][4], m[2][4], m[3][4], m[4][4], m[5][4], m[6][4] }
+ local c = do_concat(old,{1,0,0,1,b[4],a[4]})
+ for i=1,6 do
+ m[i] = { 'real', 'unlimited', 'literal', c[i] }
+ end
+ tf[5] = 6
+ push_opstack(tf)
+ else
+ local b = pop_opstack()
+ local ta = a[1]
+ local tb = b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ gsstate.matrix = do_concat(gsstate.matrix,{1,0,0,1,b[4],a[4]})
+ end
+ return true
+end
+
+function operators.scale()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'array' then
+ local tf = a
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local a = pop_opstack()
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ local v = VM[tf[4]]
+ local c = do_concat (
+ { v[1][4], v[2][4], v[3][4], v[4][4], v[5][4], v[6][4] },
+ { b[4], 0, 0, a[4], 0, 0 }
+ )
+ for i=1,6 do
+ v[i] = { 'real', 'unlimited', 'literal', c[i] }
+ end
+ tf[5] = 6
+ push_opstack(tf)
+ else
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb = a[1], b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ gsstate.matrix = do_concat(gsstate.matrix, { b[4], 0, 0, a[4], 0, 0 })
+ end
+ return true
+end
+
+function operators.concat()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= "array" then
+ return ps_error('typecheck')
+ end
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local thearray = get_VM(a[4])
+ local l = { }
+ for i=1,#thearray do
+ local v = thearray[i]
+ local t = v[1]
+ if not (t == 'real' or t == 'integer') then
+ return ps_error('typecheck')
+ end
+ l[i] = v[4]
+ end
+ gsstate.matrix = do_concat(gsstate.matrix,l)
+ return true
+end
+
+function operators.concatmatrix()
+ local tf = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if tf[1] ~= "array" then return ps_error('typecheck') end
+ if b [1] ~= "array" then return ps_error('typecheck') end
+ if a [1] ~= "array" then return ps_error('typecheck') end
+ if tf[6] ~= 6 then return ps_error('typecheck') end
+ if b [6] ~= 6 then return ps_error('typecheck') end
+ if a [6] ~= 6 then return ps_error('typecheck') end
+ local al = { }
+ local thearray = get_VM(a[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return ps_error('typecheck')
+ end
+ al[i] = v[4]
+ end
+ local bl = { }
+ local thearray = get_VM(b[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return ps_error('typecheck')
+ end
+ bl[i] = v[4]
+ end
+ local c = do_concat(al, bl)
+ local m = VM[tf[4]]
+ for i=1,6 do
+ m[i] = { 'real', 'unlimited', 'literal', c[i] }
+ end
+ tf[5] = 6
+ push_opstack(tf)
+ return true
+end
+
+function operators.rotate()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ if ta == 'array' then
+ local tf
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ tf = a
+ a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'real' or a[1] == 'integer') then
+ return ps_error('typecheck')
+ end
+ local m = VM[tf[4]]
+ local old = { m[1][4], m[2][4], m[3][4], m[4][4], m[5][4], m[6][4] }
+ local av = a[4]
+ local c = do_concat (old, {cos(rad(av)),sin(rad(av)),-sin(rad(av)),cos(rad(av)), 0, 0})
+ for i=1,6 do
+ m[i] = { 'real', 'unlimited', 'literal', c[i] }
+ end
+ push_opstack(tf)
+ elseif ta == 'real' or ta == 'integer' then
+ local av = a[4]
+ gsstate.matrix = do_concat(gsstate.matrix,{cos(rad(av)),sin(rad(av)),-sin(rad(av)),cos(rad(av)),0,0})
+ else
+ return ps_error('typecheck')
+ end
+ return true
+end
+
+function operators.transform()
+ local a = pop_opstack()
+ local b = pop_opstack()
+ if not b then
+ ps_error('stackunderflow')
+ end
+ local tf
+ if a[1] == 'array' then
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local thearray = get_VM(a[4])
+ tf = { }
+ for i=1,#thearray do
+ local v = thearray[i]
+ local v1 = v[1]
+ if not (v1 == 'real' or v1 == 'integer') then
+ return ps_error('typecheck')
+ end
+ tf[i] = v[4]
+ end
+ a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ else
+ tf = gsstate.matrix
+ end
+ local a1 = a[1]
+ local b1 = b[1]
+ if not (a1 == 'real' or a1 == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (b1 == 'real' or b1 == 'integer') then
+ return ps_error('typecheck')
+ end
+ local x, y = do_transform(tf,b[4],a[4]);
+ push_opstack { 'real', 'unlimited', 'literal', x }
+ push_opstack { 'real', 'unlimited', 'literal', y }
+ return true
+end
+
+local function commontransform()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local tf
+ if a[1] == 'array' then
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ tf = { }
+ local thearray = get_VM(a[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return ps_error('typecheck')
+ end
+ tf[i] = v[4]
+ end
+ a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ else
+ tf = gsstate.matrix
+ end
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ local ta = a[1]
+ local tb = b[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ return true, tf, a, b
+end
+
+function operators.dtransform()
+ local ok, tf, a, b = commontransform()
+ if ok then
+ local x, y = do_transform({tf[1],tf[2],tf[3],tf[4],0,0},b[4],a[4])
+ if not x then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'real', 'unlimited', 'literal', x }
+ push_opstack { 'real', 'unlimited', 'literal', y }
+ return true
+ else
+ return false, tf
+ end
+end
+
+function operators.itransform()
+ local ok, tf, a, b = commontransform()
+ if ok then
+ local x, y = do_itransform(tf,b[4],a[4])
+ if not x then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'real', 'unlimited', 'literal', x }
+ push_opstack { 'real', 'unlimited', 'literal', y }
+ return true
+ else
+ return false, tf
+ end
+end
+
+function operators.idtransform()
+ local ok, tf, a, b = commontransform()
+ if ok then
+ local x,y = do_itransform({tf[1],tf[2],tf[3],tf[4],0,0},b[4],a[4]);
+ if not x then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'real', 'unlimited', 'literal', x }
+ push_opstack { 'real', 'unlimited', 'literal', y }
+ return true
+ else
+ return false, tf
+ end
+end
+
+function operators.invertmatrix()
+ local tf = pop_opstack()
+ if not tf then
+ return ps_error('stackunderflow')
+ end
+ if tf[1] ~= "array" then
+ return ps_error('typecheck')
+ end
+ if tf[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= "array" then
+ return ps_error('typecheck')
+ end
+ if a[6] ~= 6 then
+ return ps_error('typecheck')
+ end
+ local al = { }
+ local thearray = get_VM(a[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return ps_error('typecheck')
+ end
+ al[i] = v[4]
+ end
+ local c = do_inverse(al)
+ if not c then
+ return ps_error('undefinedresult')
+ end
+ local m = VM[tf[4]]
+ for i=1,6 do
+ m[i] = { 'real', 'unlimited', 'literal', c[i] }
+ end
+ tf[5] = 6
+ push_opstack(tf)
+ return true
+end
+
+-- Path construction operators
+--
+-- +newpath +currentpoint +moveto +rmoveto +lineto +rlineto +arc +arcn +arcto +curveto +rcurveto
+-- +closepath +flattenpath -reversepath -strokepath -charpath +clippath -pathbbox -pathforall
+-- +initclip *clip *eoclip
+
+function operators.newpath()
+ gsstate.path = { }
+ gsstate.position = { }
+ return true
+end
+
+function operators.currentpoint()
+ local position = gsstate.position
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y = do_itransform(gsstate.matrix, position[1], position[2])
+ if not x then
+ return ps_error('undefinedresult')
+ end
+ push_opstack { 'real', 'unlimited', 'literal', x }
+ push_opstack { 'real', 'unlimited', 'literal', y }
+end
+
+function operators.moveto()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local b1 = b[1]
+ local a1 = a[1]
+ if not (b1 == 'real' or b1 == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (a1 == 'real' or a1 == 'integer') then
+ return ps_error('typecheck')
+ end
+ local path = gsstate.path
+ local length = #path
+ local x, y = do_transform(gsstate.matrix, a[4], b[4])
+ if length > 0 and path[length][1] == "moveto" then
+ -- replace last moveto
+ else
+ length = length + 1
+ end
+ path[length] = { "moveto", x, y }
+ gsstate.position = { x, y }
+ return true
+end
+
+function operators.rmoveto()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local bt = b[1]
+ local at = a[1]
+ if not (bt == 'real' or bt == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (at == 'real' or at == 'integer') then
+ return ps_error('typecheck')
+ end
+ local position = gsstate.position
+ local path = gsstate.path
+ local length = #path
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y = do_transform(gsstate.matrix, a[4], b[4])
+ x = position[1] + x
+ y = position[2] + y
+ position[1] = x
+ position[2] = y
+ if length > 0 and path[length][1] == "moveto" then
+ -- replace last moveto
+ else
+ length = length + 1
+ end
+ path[length] = { "moveto", x, y }
+ return true
+end
+
+function operators.lineto()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local at = a[1]
+ local bt = b[1]
+ if not (bt == 'real' or bt == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (at == 'real' or at == 'integer') then
+ return ps_error('typecheck')
+ end
+ local position = gsstate.position
+ local path = gsstate.path
+ local length = #path
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y = do_transform(gsstate.matrix, a[4], b[4])
+ gsstate.position = { x, y }
+ path[length+1] = { "lineto", x, y }
+ return true
+end
+
+function operators.rlineto()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local at = a[1]
+ local bt = b[1]
+ if not (bt == 'real' or bt == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (at == 'real' or at == 'integer') then
+ return ps_error('typecheck')
+ end
+ local position = gsstate.position
+ local path = gsstate.path
+ local length = #path
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y = do_transform(gsstate.matrix, a[4], b[4])
+ x = position[1] + x
+ y = position[2] + y
+ position[1] = x
+ position[2] = y
+ path[length+1] = { "lineto", x, y }
+ return true
+end
+
+local function arc_to_curve (x, y, r, aa, theta)
+ local th = rad(theta/2.0)
+ local x0 = cos(th)
+ local y0 = sin(th)
+ local x1 = (4.0-x0)/3.0
+ local y1 = ((1.0-x0)*(3.0-x0))/(3.0*y0) -- y0 != 0...
+ local x2 = x1
+ local y2 = -y1
+ -- local x3 = x0
+ -- local y3 = -y0
+
+ local bezAng = rad(aa) + th
+ local cBezAng = cos(bezAng)
+ local sBezAng = sin(bezAng)
+
+ local rx0 = (cBezAng * x0) - (sBezAng * y0)
+ local ry0 = (sBezAng * x0) + (cBezAng * y0)
+ local rx1 = (cBezAng * x1) - (sBezAng * y1)
+ local ry1 = (sBezAng * x1) + (cBezAng * y1)
+ local rx2 = (cBezAng * x2) - (sBezAng * y2)
+ local ry2 = (sBezAng * x2) + (cBezAng * y2)
+ -- local rx3 = (cBezAng * x3) - (sBezAng * y3)
+ -- local ry3 = (sBezAng * x3) + (cBezAng * y3)
+
+ local px0 = x + r*rx0
+ local py0 = y + r*ry0
+ local px1 = x + r*rx1
+ local py1 = y + r*ry1
+ local px2 = x + r*rx2
+ local py2 = y + r*ry2
+ -- local px3 = x + r*rx3
+ -- local py3 = y + r*ry3
+
+ return px2, py2, px1, py1, px0, py0 -- no px3, py3
+end
+
+local function arc_start(x,y,r,aa)
+ local x3 = 1
+ local y3 = 0
+ local bezAng = rad(aa)
+ local cBezAng = cos(bezAng)
+ local sBezAng = sin(bezAng)
+ local rx3 = (cBezAng * x3) - (sBezAng * y3)
+ local ry3 = (sBezAng * x3) + (cBezAng * y3)
+ local px3 = x + r*rx3
+ local py3 = y + r*ry3
+ return px3, py3
+end
+
+local function do_arc(matrix,path,x,y,r,aa,ab)
+ local endx, endy
+ local segments = floor((ab-aa+44.999999999)/45)
+ if segments == 0 then
+ return do_transform(gsstate.matrix, x,y)
+ end
+ local theta = (ab-aa) / segments
+ while segments>0 do
+ local x1, y1, x2, y2, x3, y3 = arc_to_curve(x,y,r,aa,theta)
+ local px2, py2 = do_transform(matrix,x2,y2)
+ local px1, py1 = do_transform(matrix,x1,y1)
+ endx, endy = do_transform(matrix, x3,y3)
+ path[#path+1] = { "curveto", px1, py1, px2, py2, endx, endy }
+ segments = segments - 1
+ aa = aa + theta
+ end
+ return endx, endy
+end
+
+local function do_arcn(matrix,path,x,y,r,aa,ab)
+ local endx, endy
+ local segments = floor((aa-ab+44.999999999)/45)
+ if segments == 0 then
+ return do_transform(matrix, x,y)
+ end
+ local theta = (aa-ab) / segments
+ while segments > 0 do
+ local x1, y1, x2, y2, x3, y3 = arc_to_curve(x,y,r,aa,-theta)
+ local px1, py1 = do_transform(matrix,x1,y1)
+ local px2, py2 = do_transform(matrix,x2,y2)
+ endx, endy = do_transform(matrix,x3,y3)
+ path[#path+1] = { "curveto", px1 , py1 , px2 , py2 , endx , endy }
+ segments = segments - 1
+ aa = aa - theta
+ end
+ return endx, endy
+end
+
+local function commonarc(action)
+ local e = pop_opstack()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc, td, te = a[1], b[1], c[1], d[1], e[1], f[1]
+ if not (ta == 'real' or ta == 'integer') then return ps_error('typecheck') end
+ if not (tb == 'real' or tb == 'integer') then return ps_error('typecheck') end
+ if not (tc == 'real' or tc == 'integer') then return ps_error('typecheck') end
+ if not (td == 'real' or td == 'integer') then return ps_error('typecheck') end
+ if not (te == 'real' or te == 'integer') then return ps_error('typecheck') end
+ local position = gsstate.position
+ local path = gsstate.path
+ local matrix = gsstate.matrix
+ local vd = d[4]
+ local ve = e[4]
+ if vd < 0 or ve < 0 or vd > 360 or ve > 360 or (vd-ve) <= 0 then
+ return ps_error('limitcheck')
+ end
+ local r = c[4]
+ if r == 0 then
+ ps_error('limitcheck')
+ end
+ local x = a[4]
+ local y = b[4]
+ local x0, y0 = arc_start(x,y,r,vd) -- find starting points
+ local startx, starty = do_transform(matrix,x0,y0)
+ path[#path+1] = { #position == 2 and "lineto" or "moveto", startx, starty }
+ position[1], position[2] = action(matrix,path,x,y,r,vd,ve)
+ return true
+end
+
+function operators.arc()
+ commonarc(do_arc)
+end
+
+function operators.arcn()
+ commonarc(do_arcn)
+end
+
+local function vlength (a,b)
+ return sqrt(a^2+b^2)
+end
+
+local function vscal_ (a,b,c)
+ return a*b, a*c
+end
+
+-- this is of_the_way
+
+local function between (dist, pa, pb)
+ local pa1, pa2 = pa[1], pa[2]
+ local pb1, pb2 = pb[1], pb[2]
+ return {
+ pa1 + dist * (pb1 - pa1),
+ pa2 + dist * (pb2 - pa2),
+ }
+end
+
+local function sign (a)
+ return a < 0 and -1 or 1
+end
+
+local function do_arcto(x,y,r) -- todo: check with original
+ local h = gsstate.position
+ local tx1, tx2, ty1, ty2
+ local c1, c2
+ local x1, x2 = x[1], x[2]
+ local y1, y2 = y[1], y[2]
+ local h1, h2 = h[1], h[2]
+ local ux, uy = x1 - h1, x2 - h2
+ local vx, vy = y1 - x1, y2 - x2
+ local lx, ly = vlength(ux,uy), vlength(vx,vy)
+ local sx, sy = ux*vy - uy*vx, ux*vx + uy*vy
+ if sx == 0 and sy == 0 then
+ sx = r
+ sy = 0
+ else
+ sx = r
+ sy = atan2(sx,sy)
+ end
+ local a_arcto = sx*tan(abs(sy)/2)
+ if sx*sy*lx*ly == 0 then
+ tx1 = x1
+ tx2 = x2
+ ty1 = x1
+ ty2 = x2
+ c1 = x1
+ c2 = x2
+ else
+ local tx = between(a_arcto/lx,x,h)
+ local ty = between(a_arcto/ly,x,y)
+ local cc, dd = vscal_(sign(sy)*sx/lx,-uy,ux)
+ tx1 = tx[1]
+ tx2 = tx[2]
+ ty1 = ty[1]
+ ty2 = ty[2]
+ c1 = tx1 + cc
+ c2 = tx2 + dd
+ end
+ -- now tx is the starting point, ty is the endpoint,
+ -- c is the center of the circle. find the two angles
+ local anga = deg(atan2(tx2-c2,tx1-c1)) -- todo, -90 is wrong
+ local angb = deg(atan2(ty2-c2,ty1-c1)) -- todo, -90 is wrong
+ return c1, c2, r, anga, angb, tx1, tx2, ty1, ty2
+end
+
+function operators.arcto()
+ local e = pop_opstack()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc, td, te = a[1], b[2], c[1], d[1], e[1]
+ if not (ta == 'real' or ta == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tc == 'real' or tc == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (td == 'real' or td == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (te == 'real' or te == 'integer') then
+ return ps_error('typecheck')
+ end
+ local x1, y1, x2, y2, r = a[4], b[4], c[4], d[4], e[4]
+ local position = gsstate.position
+ local path = gsstate.path
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y, r, anga, angb, tx1, tx2, ty1, ty2 = do_arcto({x1,y1},{x2, y2},r)
+ local vx, vy = do_transform(gsstate.matrix,tx1,tx2)
+ path[#path+1] = { "lineto", vx, vy }
+ if anga == angb then
+ -- do nothing
+ elseif anga > angb then
+ position[1], position[2] = do_arcn(x,y,r,anga,angb)
+ else
+ position[1], position[2] = do_arc (x,y,r,anga,angb)
+ end
+ push_opstack { 'real', 'unlimited', 'literal', tx1 }
+ push_opstack { 'real', 'unlimited', 'literal', tx2 }
+ push_opstack { 'real', 'unlimited', 'literal', ty1 }
+ push_opstack { 'real', 'unlimited', 'literal', ty2 }
+end
+
+function operators.curveto()
+ local f = pop_opstack()
+ local e = pop_opstack()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local f1 = f[1] if not (f1 == 'real' or f1 == 'integer') then return ps_error('typecheck') end
+ local e1 = e[1] if not (e1 == 'real' or e1 == 'integer') then return ps_error('typecheck') end
+ local d1 = d[1] if not (d1 == 'real' or d1 == 'integer') then return ps_error('typecheck') end
+ local c1 = c[1] if not (c1 == 'real' or c1 == 'integer') then return ps_error('typecheck') end
+ local b1 = b[1] if not (b1 == 'real' or b1 == 'integer') then return ps_error('typecheck') end
+ local a1 = a[1] if not (a1 == 'real' or a1 == 'integer') then return ps_error('typecheck') end
+ --
+ if #gsstate.position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ --
+ local matrix = gsstate.matrix
+ local x, y = do_transform(matrix, e[4], f[4])
+ local ax, ay = do_transform(matrix, a[4], b[4])
+ local bx, by = do_transform(matrix, c[4], d[4])
+ gsstate.position = { x, y }
+ --
+ local path = gsstate.path
+ path[#path+1] = { "curveto", ax, ay, bx, by, x, y }
+ return true
+end
+
+function operators.rcurveto()
+ local f = pop_opstack()
+ local e = pop_opstack()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ft if not (ft == 'real' or ft == 'integer') then return ps_error('typecheck') end
+ local et if not (et == 'real' or et == 'integer') then return ps_error('typecheck') end
+ local dt if not (dt == 'real' or dt == 'integer') then return ps_error('typecheck') end
+ local ct if not (ct == 'real' or ct == 'integer') then return ps_error('typecheck') end
+ local bt if not (bt == 'real' or bt == 'integer') then return ps_error('typecheck') end
+ local at if not (at == 'real' or at == 'integer') then return ps_error('typecheck') end
+ local position = gsstate.position
+ local path = gsstate.path
+ if #position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ local x, y = do_transform(matrix, e[4], f[4])
+ local ax, ay = do_transform(matrix, a[4], b[4])
+ local bx, by = do_transform(matrix, c[4], d[4])
+ local px = position[1] + x
+ local py = position[2] + y
+ path[#path+1] = {
+ "curveto",
+ position[1] + ax,
+ position[2] + ay,
+ position[1] + bx,
+ position[2] + by,
+ px,
+ py
+ }
+ position[1] = px
+ position[2] = py
+ return true
+end
+
+function operators.closepath()
+ local path = gsstate.path
+ local length = #path
+ if length > 0 and path[length][1] ~= 'closepath' then
+ local m = path[1]
+ local a = m[2]
+ local b = m[3]
+ local x, y = do_transform(gsstate.matrix, a, b)
+ gsstate.position = { x, y }
+ path[length+1] = { "closepath", x, y }
+ end
+ return true
+end
+
+-- finds a point on a bezier curve
+-- P(x,y) = (1-t)^3*(x0,y0)+3*(1-t)^2*t*(x1,y1)+3*(1-t)*t^2*(x2,y2)+t^3*(x3,y3)
+
+local function bezier_at(t,x0,y0,x1,y1,x2,y2,x3,y3)
+ local v = (1 - t)
+ local x = (v^3)*x0 + 3*(v^2)*t*x1 + 3*v*(t^2)*x2 + (t^3)*x3
+ local y = (v^3)*y0 + 3*(v^2)*t*y1 + 3*v*(t^2)*y2 + (t^3)*y3
+ return x, y
+end
+
+local delta = 10 -- 100
+
+local function good_enough (flatness,c,ct1,ct2,l)
+ local c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y = c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]
+ local l0x, l0y, l1x, l1y = l[1], l[2], l[3], l[4]
+ local t = 0
+ while t < delta do
+ local td = t/delta
+ local bx, by = bezier_at(ct1+(ct2-ct1)*td,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y)
+ local lx, ly = (1-td)*l0x + td*l1x, (1-td)*l0y + td*l1y
+ local dist = vlength(bx-lx,by-ly)
+ if dist > flatness then
+ return false
+ end
+ t = t + 1
+ end
+ return true
+end
+
+-- argument d is recursion depth, 10 levels should be enough to reach a conclusion
+-- (and already generates over 1000 lineto's in the worst case)
+
+local function splitter (flatness,p,d,c,ct1,ct2,l)
+ local c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y = c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]
+ d = d + 1
+ local r = good_enough(flatness,c,ct1,ct1+ct2,l)
+ if r or d > 10 then
+ p[#p + 1] = { 'lineto', l[3], l[4] }
+ else
+ local ct22 = ct2/2
+ local l2x, l2y = bezier_at(ct1+ct22,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y)
+ local l1 = { l[1], l[2], l2x, l2y }
+ local l2 = { l2x, l2y, l[3], l[4] }
+ splitter(flatness,p,d,c,ct1,ct22,l1)
+ splitter(flatness,p,d,c,ct1+ct22,ct22,l2)
+ end
+end
+
+local function flattencurve( homex, homey, curve, flatness)
+ local p = { }
+ local c6 = curve[6]
+ local c7 = curve[7]
+ local thecurve = { homex, homey, curve[2], curve[3], curve[4], curve[5], c6, c7 }
+ local theline = { homex, homey, c6, c7 }
+ splitter(flatness, p, 0, thecurve, 0, 1, theline)
+ return p
+end
+
+local function do_flattenpath (p, flatness)
+ local x, y
+ local px = { }
+ local nx = 0
+ -- we don't care about differences less than a a permille of a point, ever
+ if flatness < 0.001 then
+ flatness = 0.001
+ end
+ if p then
+ for i=1,#p do
+ local v = p[i]
+ local t = v[1]
+ if t == "curveto" then
+ local pxl = flattencurve(x,y,v,flatness)
+ for i=1,#pxl do
+ nx = nx + 1 ; px[nx] = pxl[i]
+ end
+ x, y = v[6], v[7]
+ elseif t == "lineto" or t == "moveto" then
+ x, y = v[2], v[3]
+ nx = nx + 1 ; px[nx] = v
+ else
+ nx = nx + 1 ; px[nx] = v
+ end
+ end
+ end
+ return px
+end
+
+function operators.flattenpath()
+ gsstate.path = do_flattenpath(gsstate.path,gsstate.flatness)
+end
+
+function operators.clippath()
+ gsstate.path = gsstate.clip
+ return true
+end
+
+function operators.initclip()
+ device.initclip()
+ return true
+end
+
+function operators.eofill()
+ local color = gsstate.color
+ local thecolor = color[color.type]
+ if type(thecolor) == "table" then
+ thecolor = { unpack(thecolor) }
+ end
+ currentpage[#currentpage+1] = {
+ type = 'eofill',
+ path = gsstate.path,
+ colortype = color.type,
+ color = thecolor,
+ }
+ operators.newpath()
+ return true
+end
+
+-- todo: this only fixes the output, not the actual clipping path
+-- in the gsstate !
+
+function operators.clip()
+ currentpage[#currentpage+1] = {
+ type = 'clip',
+ path = gsstate.path,
+ }
+ return true
+end
+
+-- todo: this only fixes the output, not the actual clipping path
+-- in the gsstate !
+
+function operators.eoclip()
+ currentpage[#currentpage+1] = {
+ type = 'eoclip',
+ path = gsstate.path,
+ }
+ return true
+end
+
+-- Painting operators
+--
+-- +erasepage +fill +eofill +stroke -image -imagemask
+
+-- general graphics todo: transfer function, flatness
+
+function operators.erasepage()
+ currentpage = { }
+ return true
+end
+
+function operators.stroke()
+ local color = gsstate.color
+ local ctype = color.type
+ local thecolor = color[ctype]
+ -- if type(thecolor) == "table" then
+ -- thecolor = { unpack(thecolor) }
+ -- end
+ currentpage[#currentpage+1] = {
+ type = 'stroke',
+ path = gsstate.path,
+ colortype = ctype,
+ color = thecolor,
+ miterlimit = gsstate.miterlimit,
+ linewidth = gsstate.linewidth,
+ linecap = gsstate.linecap,
+ linejoin = gsstate.linejoin,
+ -- dashpattern = { unpack (gsstate.dashpattern) }, -- unpack? we don't manipulate
+ dashpattern = gsstate.dashpattern,
+ dashoffset = gsstate.dashoffset
+ }
+ operators.newpath()
+ return true
+end
+
+function operators.fill()
+ local color = gsstate.color
+ local ctype = color.type
+ local thecolor = color[ctype]
+ -- if type(thecolor) == "table" then
+ -- thecolor = { unpack(thecolor) }
+ -- end
+ currentpage[#currentpage+1] = {
+ type = 'fill',
+ path = gsstate.path,
+ colortype = ctype,
+ color = thecolor,
+ }
+ operators.newpath()
+ return true
+end
+
+-- Device setup and output operators
+--
+-- +showpage +copypage +banddevice +framedevice +nulldevice +renderbands
+
+-- will be replaced by the argument of 'new'
+
+-- this reports the bounding box of a page
+
+-- todo: linewidth for strokes
+-- todo: clips
+-- todo: strings (width&height)
+
+local calculatebox = false
+
+initializers[#initializers+1] = function()
+ calculatebox = true
+end
+
+local function boundingbox(page)
+
+ local bounding = specials.boundingbox
+ if bounding and not calculatebox then
+ return unpack(bounding)
+ end
+
+ local minx, miny, maxx, maxy
+ local startx, starty
+ local linewidth
+
+ local function update_bbox (x,y)
+ if not minx then
+ minx = x
+ miny = y
+ maxx = x
+ maxy = y
+ end
+ if linewidth then
+ local xx = x + linewidth/2
+ if xx > maxx then maxx = xx elseif xx < minx then minx = xx end
+ local xx = x - linewidth/2
+ if xx > maxx then maxx = xx elseif xx < minx then minx = xx end
+ local yy = y + linewidth/2
+ if yy > maxy then maxy = yy elseif yy < miny then miny = yy end
+ local yy = y - linewidth/2
+ if yy > maxy then maxy = yy elseif yy < miny then miny = yy end
+ else
+ if x > maxx then maxx = x elseif x < minx then minx = x end
+ if y > maxy then maxy = y elseif y < miny then miny = y end
+ end
+ startx, starty = x, y
+ end
+
+ for i=1,#page do
+ local object = page[i]
+ local p = do_flattenpath(object.path,0.5)
+ linewidth = object.type == "stroke" and object.linewidth
+ for i=1,#p do
+ local segment = p[i]
+ local type = segment[1]
+ if type == "lineto" then
+ if startx then
+ update_bbox(startx,starty)
+ end
+ update_bbox(segment[2],segment[3])
+ elseif type == "curveto" then
+ if startx then
+ update_bbox(startx,starty)
+ end
+ update_bbox(segment[6],segment[7])
+ elseif type == "moveto" then
+ startx, starty = segment[2], segment[3]
+ end
+ end
+ end
+ if minx then
+ return minx, miny, maxx, maxy
+ else
+ return 0, 0, 0, 0
+ end
+end
+
+------------------------------------------------------------------
+
+local function boundingbox (page)
+
+ local bounding = specials.boundingbox
+ if bounding and not calculatebox then
+ return unpack(bounding)
+ end
+
+ local minx, miny, maxx, maxy
+ local startx, starty
+ local linewidth
+
+ local function update_bbox (x,y)
+ if not minx then
+ minx = x
+ miny = y
+ maxx = x
+ maxy = y
+ end
+ if linewidth then
+ local xx = x + linewidth/2
+ if xx > maxx then
+ maxx = xx
+ elseif xx < minx then
+ minx = xx
+ end
+ local xx = x - linewidth/2
+ if xx > maxx then
+ maxx = xx
+ elseif xx < minx then
+ minx = xx
+ end
+ local yy = y + linewidth/2
+ if yy > maxy then
+ maxy = yy
+ elseif yy < miny then
+ miny = yy
+ end
+ local yy = y - linewidth/2
+ if yy > maxy then
+ maxy = yy
+ elseif yy < miny then
+ miny = yy
+ end
+ else
+ if x > maxx then
+ maxx = x
+ elseif x < minx then
+ minx = x
+ end
+ if y > maxy then
+ maxy = y
+ elseif y < miny then
+ miny = y
+ end
+ end
+ startx, starty = x, y
+ end
+
+ local delta = 10 -- 100
+
+ local function good_enough (ct1,ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y)
+ local t = 0
+ while t < delta do
+ local td = t/delta
+ local bx, by = bezier_at(ct1+(ct2-ct1)*td,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y)
+ local lx, ly = (1-td)*l0x + td*l1x, (1-td)*l0y + td*l1y
+ local dist = sqrt((bx-lx)^2+(by-ly)^2) -- vlength(bx-lx,by-ly)
+ if dist > 0.5 then
+ return false
+ end
+ t = t + 1
+ end
+ return true
+ end
+
+ local function splitter (d,ct1,ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y)
+ d = d + 1
+ local r = good_enough(ct1,ct1+ct2, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l1x, l1y)
+ if r or d > 10 then
+ if startx then
+ update_bbox(l1x, l1y)
+ end
+ else
+ local ct22 = ct2/2
+ local l2x, l2y = bezier_at(ct1+ct22,c0x,c0y,c1x,c1y,c2x,c2y,c3x,c3y)
+ splitter(d,ct1, ct22, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l0x, l0y, l2x, l2y)
+ splitter(d,ct1+ct22,ct22, c0x, c0y, c1x, c1y, c2x, c2y, c3x, c3y, l2x, l2y, l1x, l1y)
+ end
+ end
+
+ for i=1,#page do
+ local object = page[i]
+ local p = object.path
+ linewidth = object.type == "stroke" and object.linewidth
+ for i=1,#p do
+ local segment = p[i]
+ local type = segment[1]
+ if type == "lineto" then
+ if startx then
+ update_bbox(startx,starty)
+ end
+ update_bbox(segment[2],segment[3])
+ elseif type == "curveto" then
+ local c6 = segment[6]
+ local c7 = segment[7]
+ splitter(0, 0, 1, startx, starty, segment[2], segment[3], segment[4], segment[5], c6, c7, startx, starty, c6, c7)
+ elseif type == "moveto" then
+ startx, starty = segment[2], segment[3]
+ end
+ end
+ end
+ if minx then
+ return minx, miny, maxx, maxy
+ else
+ return 0, 0, 0, 0
+ end
+end
+
+------------------------------------------------------------------
+
+-- most time is spend in calculating the boundingbox
+
+-- NULL output
+
+devices.null = {
+ initgraphics = function() gsstate.matrix = { 1, 0, 0, 1, 0, 0 } end,
+ initclip = function() gsstate.clip = { } end,
+ showpage = function() return "" end,
+}
+
+-- PDF output
+
+local pdf = {
+ initgraphics = function() gsstate.matrix = { 1, 0, 0, 1, 0, 0 } end,
+ initclip = function() gsstate.clip = { } end,
+ -- startpage = function(llc,lly,urx,ury) end,
+ -- flushpage = function() end,
+ -- stoppage = function() end,
+}
+
+devices.pdf = pdf
+
+function pdf.showpage(page)
+ --
+ local startpage = pdf.startpage
+ local stoppage = pdf.stoppage
+ local flushpage = pdf.flushpage
+ local showfont = pdf.showfont
+ --
+ if not flushpage then
+ return
+ end
+ --
+ if startpage then
+ startpage(boundingbox(page))
+ end
+ --
+ local t = { "q" }
+ local n = 1
+ local g_colortype = "notacolor"
+ local g_color = ""
+ local g_miterlimit = -1
+ local g_linejoin = -1
+ local g_linecap = -1
+ local g_linewidth = -1
+ local g_dashpattern = nil
+ local g_dashoffset = -1
+ local flush = devices.pdf.flush
+ for i=1,#page do
+ local object = page[i]
+ local path = object.path
+ local otyp = object.type
+ if otype ~= "clip" and otype ~= "eoclip" then
+ local colortype = object.colortype
+ local color = object.color
+ if colortype == "gray" then
+ local v = formatters["%f g %f G"](color,color)
+ if g_color ~= v then
+ g_colortype = "gray"
+ g_color = v
+ n = n + 1 ; t[n] = v
+ end
+ elseif colortype == "rgb" then
+ local r, g, b = color[1], color[2], color[3]
+ local v = formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b)
+ if g_color ~= v then
+ g_colortype = "rgb"
+ g_color = v
+ n = n + 1 ; t[n] = v
+ end
+ elseif colortype == "cmyk" then
+ local c, m, y, k = color[1], color[2], color[3], color[4]
+ local v = formatters["%f %f %f %f k %f %f %f %f K"](c,m,y,k,c,m,y,k)
+ if g_color ~= v then
+ g_colortype = "cmyk"
+ g_color = v
+ n = n + 1 ; t[n] = v
+ end
+ elseif colortype == "hsb" then
+ local r, g, b = hsv_to_rgb(color[1],color[2],color[3])
+ local v = formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b)
+ if g_color ~= v then
+ g_colortype = "rgb"
+ g_color = v
+ n = n + 1 ; t[n] = v
+ end
+ end
+ end
+ if otype == "stroke" then
+ local miterlimit = object.miterlimit
+ if g_miterlimit ~= miterlimit then
+ g_miterlimit = miterlimit
+ n = n + 1 ; t[n] = formatters["%f M"](miterlimit)
+ end
+ local linejoin = object.linejoin
+ if g_linejoin ~= linejoin then
+ g_linejoin = linejoin
+ n = n + 1 ; t[n] = formatters["%d j"](linejoin)
+ end
+ local linecap = object.linecap
+ if g_linecap ~= linecap then
+ g_linecap = linecap
+ n = n + 1 ; t[n] = formatters["%d J"](linecap)
+ end
+ local linewidth = object.linewidth
+ if g_linewidth ~= linewidth then
+ g_linewidth = linewidth
+ n = n + 1 ; t[n] = formatters["%f w"](linewidth)
+ end
+ local dashpattern = object.dashpattern
+ local dashoffset = object.dashoffset
+ if g_dashpattern ~= dashpattern or g_dashoffset ~= dashoffset then
+ g_dashpattern = dashpattern
+ g_dashoffset = dashoffset
+ local l = #dashpattern
+ if l == 0 then
+ n = n + 1 ; t[n] = "[] 0 d"
+ else
+ n = n + 1 ; t[n] = formatters["[% t] %d d"](dashpattern,dashoffset)
+ end
+ end
+ end
+ if path then
+ for i=1,#path do
+ local segment = path[i]
+ local styp = segment[1]
+ if styp == "moveto" then
+ n = n + 1 ; t[n] = formatters["%f %f m"](segment[2],segment[3])
+ elseif styp == "lineto" then
+ n = n + 1 ; t[n] = formatters["%f %f l"](segment[2],segment[3])
+ elseif styp == "curveto" then
+ n = n + 1 ; t[n] = formatters["%f %f %f %f %f %f c"](segment[2],segment[3],segment[4],segment[5],segment[6],segment[7])
+ elseif styp == "closepath" then
+ n = n + 1 ; t[n] = "h"
+ else
+ report("unknown path segment type %a",styp)
+ end
+ end
+ end
+ if otyp == "stroke" then
+ n = n + 1 ; t[n] = "S"
+ elseif otyp == "fill" then
+ n = n + 1 ; t[n] = "f"
+ elseif otyp == "eofill" then
+ n = n + 1 ; t[n] = "f*"
+ elseif otyp == "clip" then
+ n = n + 1 ; t[n] = "W n"
+ elseif otyp == "eoclip" then
+ n = n + 1 ; t[n] = "W* n"
+ elseif otyp == "show" then
+ if showfont then
+ if n > 0 then
+ flushpage(concat(t,"\n"))
+ n = 0 ; t = { }
+ end
+ showfont(object)
+ end
+ else
+ -- nothing to do
+ end
+ end
+ n = n + 1 ; t[n] = "Q"
+ flushpage(concat(t,"\n"))
+ --
+ if startpage then
+ stoppage()
+ end
+end
+
+function operators.showpage()
+ local copies = lookup("#copies")
+ if copies and copies[1] == 'integer' and copies[4] >= 1 then
+ local amount = floor(copies[4])
+ local render = device.showpage
+ if render then
+ for i=1,amount do
+ render(currentpage)
+ end
+ end
+ end
+ operators.erasepage()
+ operators.initgraphics()
+ return true
+end
+
+function operators.copypage()
+ local render = device.showpage
+ if render then
+ render(currentpage)
+ end
+ return true
+end
+
+function operators.banddevice()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc, td = a[1], b[1], c[1], d[1]
+ if not (ta == 'array' and a[5] == 6) then
+ return ps_error('typecheck')
+ end
+ if not (td == 'array' and d[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tc == 'real' or tc == 'integer') then
+ return ps_error('typecheck')
+ end
+ local dev = device.banddevice
+ if dev then
+ dev(a,b,c,d)
+ else
+ return ps_error('undefined') -- fixed
+ end
+ return true
+end
+
+function operators.renderbands()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if not (a[1] == 'array' and a[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ local dev = device.renderbands
+ if dev then
+ dev(d)
+ else
+ return ps_error('undefined')
+ end
+ return true
+end
+
+function operators.framedevice()
+ local d = pop_opstack()
+ local c = pop_opstack()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ local ta, tb, tc, td = a[1], b[1], c[1], d[1]
+ if not (ta == 'array' and a[5] == 6) then
+ return ps_error('typecheck')
+ end
+ if not (tb == 'real' or tb == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (tc == 'real' or tc == 'integer') then
+ return ps_error('typecheck')
+ end
+ if not (td == 'array' and d[3] == 'executable') then
+ return ps_error('typecheck')
+ end
+ local dev = device.framedevice
+ if dev then
+ dev(a,b,c,d)
+ else
+ return ps_error('undefined')
+ end
+ return true
+end
+
+function operators.nulldevice()
+ gsstate.device = "null"
+ operators.initgraphics()
+ return true
+end
+
+-- Character and font operators
+--
+-- +definefont *findfont +scalefont +makefont +setfont +currentfont +show -ashow -widthshow
+-- -awidthshow +kshow -stringwidth ^FontDirectory ^StandardEncoding
+
+-- Fonts are a bit special because it is needed to cooperate with the enclosing PDF document.
+
+local FontDirectory
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ FontDirectory = nil
+ else
+ FontDirectory = add_VM {
+ access = 'unlimited',
+ size = 0,
+ maxsize = 5000,
+ dict = { },
+ }
+ end
+end
+
+-- loading actual fonts is a worryingly slow exercise
+
+local fontmap
+
+initializers[#initializers+1] = function()
+ if reset then
+ fontmap = nil
+ else
+ fontmap = {
+ ['Courier-Bold'] = 'NimbusMonL-Bold.ps',
+ ['Courier-BoldOblique'] = 'NimbusMonL-BoldObli.ps',
+ ['Courier'] = 'NimbusMonL-Regu.ps',
+ ['Courier-Oblique'] = 'NimbusMonL-ReguObli.ps',
+ ['Times-Bold'] = 'NimbusRomNo9L-Medi.ps',
+ ['Times-BoldItalic'] = 'NimbusRomNo9L-MediItal.ps',
+ ['Times-Roman'] = 'NimbusRomNo9L-Regu.ps',
+ ['Times-Italic'] = 'NimbusRomNo9L-ReguItal.ps',
+ ['Helvetica-Bold'] = 'NimbusSanL-Bold.ps',
+ ['Helvetica-BoldOblique'] = 'NimbusSanL-BoldItal.ps',
+ ['Helvetica'] = 'NimbusSanL-Regu.ps',
+ ['Helvetica-Oblique'] = 'NimbusSanL-ReguItal.ps',
+ ['Symbol'] = 'StandardSymL.ps',
+ }
+ end
+end
+
+-- this can be overwritten by the user
+
+local function findfont(fontname)
+ return fontmap[fontname]
+end
+
+-- tests required keys in a font dict
+
+local function checkfont(f)
+ -- FontMatrix
+ local matrix = f['FontMatrix']
+ if not matrix or matrix[1] ~= 'array' or matrix[5] ~= 6 then
+ return false
+ end
+ local thearray = get_VM(matrix[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return false
+ end
+ end
+ -- FontType
+ local ftype = f['FontType']
+ if not ftype or ftype[1] ~= 'integer' then
+ return false
+ end
+ -- FontBBox
+ local bbox = f['FontBBox']
+ -- do not test [5] here, because it can be '1' (executable array)
+ if not bbox or bbox[1] ~= 'array' or bbox[6] ~= 4 then
+ return false
+ end
+ local thearray = get_VM(bbox[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return false
+ end
+ end
+ -- Encoding
+ local bbox = f['Encoding']
+ if not bbox or bbox[1] ~= 'array' or bbox[5] ~= 256 then
+ return false
+ end
+ local thearray = get_VM(bbox[4])
+ for i=1,#thearray do
+ local v = thearray[i]
+ local tv = v[1]
+ if tv[1] ~= 'name' then
+ return false
+ end
+ end
+ return true
+end
+
+-- objects of type font as essentially the same as objects of type dict
+
+function operators.definefont()
+ local b = pop_opstack()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'dict' then
+ return ps_error('typecheck')
+ end
+ -- force keys to be names
+ if a[1] ~= 'name' then
+ return ps_error('typecheck')
+ end
+ local fontdict = get_VM(b[4])
+ if not checkfont(fontdict.dict) then
+ return ps_error('invalidfont')
+ end
+ -- check that a FID will fit
+ if fontdict.size == fontdict.maxsize then
+ return ps_error('invalidfont')
+ end
+ fontdict.dict['FID'] = {'font', 'executable', 'literal', b[4]}
+ fontdict.size = fontdict.size + 1
+ fontdict.access = 'read-only'
+ local dict = get_VM(FontDirectory)
+ local key = get_VM(a[4])
+ if not dict.dict[key] and dict.size == dict.maxsize then
+ -- return ps_error('dictfull') -- level 1 only
+ end
+ if not dict.dict[key] then
+ dict.size = dict.size + 1
+ end
+ dict.dict[key] = fontdict.dict['FID']
+ push_opstack(b)
+ return true
+end
+
+function operators.findfont()
+ local a = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if a[1] ~= 'name' then
+ return ps_error('typecheck')
+ end
+ local fontdict = get_VM(FontDirectory)
+ local key = get_VM(a[4])
+ local dict = dict.dict
+ if not dict[key] then
+ fname = findfont(key)
+ if not fname then
+ return ps_error('invalidfont')
+ end
+ local oldfontkeys = { }
+ for k, v in next, dict do
+ oldfontkeys[i] = 1
+ end
+ report("loading font file %a",fname)
+ local theopstack = opstackptr
+ local run = formatters['/eexec {pop} def (%s) run'](fname)
+ push_execstack { '.stopped', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ push_execstack { 'string', 'unlimited', 'executable', add_VM(run), 1, #run }
+ while curstack < execstackptr do
+ do_exec()
+ end
+ if execstack[execstackptr][1] == '.stopped' then
+ pop_execstack()
+ end
+ opstackptr = theopstack
+ local fkey, ftab
+ for k, v in next, dict do
+ if not oldfontkeys[k] then
+ -- this is the new dict
+ fkey = k
+ ftab = v
+ break
+ end
+ end
+ if not fkey then
+ return ps_error('invalidfont')
+ end
+ dict[key] = ftab -- set up the user requested name as well
+ end
+ push_opstack(dict[key])
+ return true
+end
+
+local function pushscaledcopy(fontdict,matrix)
+ local olddict = fontdict.dict
+ if not checkfont(olddict) then
+ return ps_error('invalidfont')
+ end
+ local newdict = { }
+ local oldsize = fontdict.size
+ local newfontdict = {
+ dict = newdict,
+ access = 'read-only',
+ size = oldsize,
+ maxsize = oldsize,
+ }
+ for k, v in next, olddict do
+ if k == "FontMatrix" then
+ local oldmatrix = get_VM(v[4])
+ local old = {
+ oldmatrix[1][4],
+ oldmatrix[2][4],
+ oldmatrix[3][4],
+ oldmatrix[4][4],
+ oldmatrix[5][4],
+ oldmatrix[6][4],
+ }
+ local c = do_concat(old,matrix)
+ local new = {
+ { 'real', 'unlimited', 'literal', c[1] },
+ { 'real', 'unlimited', 'literal', c[2] },
+ { 'real', 'unlimited', 'literal', c[3] },
+ { 'real', 'unlimited', 'literal', c[4] },
+ { 'real', 'unlimited', 'literal', c[5] },
+ { 'real', 'unlimited', 'literal', c[6] }
+ }
+ newdict[k] = { 'array', 'unlimited', 'literal', add_VM(new), 6, 6 }
+ elseif k == "FID" then
+ -- updated later
+ else
+ newfontdict.dict[k] = v
+ end
+ end
+ local f = add_VM(newfontdict)
+ newdict['FID'] = { 'font', 'read-only', 'literal', f }
+ push_opstack { 'font', 'read-only', 'literal', f } -- share ?
+ return true
+end
+
+function operators.scalefont()
+ local s = pop_opstack()
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'font' then
+ return ps_error('typecheck')
+ end
+ if not (s[1] == 'integer' or s[1] == 'real') then
+ return ps_error('typecheck')
+ end
+ local scals = s[4]
+ local matrix = { scale, 0, 0, scale, 0, 0 }
+ local fontdict = get_VM(b[4])
+ return pushscaledcopy(fontdict,matrix)
+end
+
+function operators.makefont()
+ local s = pop_opstack()
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'font' then
+ return ps_error('typecheck')
+ end
+ if s[1] ~= 'array' then
+ return ps_error('typecheck')
+ end
+ if s[6] ~= 6 then
+ return ps_error('rangecheck')
+ end
+ local matrix = { }
+ local array = get_VM(s[4])
+ for i=1,#array do
+ local v = array[i]
+ local tv = v[1]
+ if not (tv == 'real' or tv == 'integer') then
+ return ps_error('typecheck')
+ end
+ matrix[i] = v[4]
+ end
+ local fontdict = get_VM(b[4])
+ pushscaledcopy(fontdict,matrix)
+ return true
+end
+
+function operators.setfont()
+ local b = pop_opstack()
+ if not b then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= 'font' then
+ return ps_error('typecheck')
+ end
+ gsstate.font = b[4]
+ return true
+end
+
+-- todo: the invalidfont error is temporary. 'start' should set up at least one font in
+-- FontDirectory and assing it as the current font
+
+function operators.currentfont()
+ if not gsstate.font then
+ return ps_error('invalidfont')
+ end
+ push_opstack {'font', 'read-only', 'literal', gsstate.font }
+ return true
+end
+
+function do_show(fontdict,s)
+ local stringmatrix = { }
+ local truematrix = { }
+ local stringencoding = { }
+ --
+ local dict = fontdict.dict
+ local fontname = get_VM(dict['FontName'][4])
+ local fontmatrix = get_VM(dict['FontMatrix'][4])
+ local encoding = get_VM(dict['Encoding'][4])
+ local matrix = gsstate.matrix
+ local position = gsstate.position
+ local color = gsstate.color
+ local colortype = color.type
+ local colordata = color[colortype]
+ --
+ if fontmatrix then
+ for i=1,#fontmatrix do
+ stringmatrix[i] = fontmatrix[i][4]
+ end
+ end
+ if matrix then
+ for i=1,#matrix do
+ truematrix[i] = matrix[i]
+ end
+ end
+ if encoding then
+ for i=1,#m do
+ stringencoding[i] = get_VM(e[i][4])
+ end
+ end
+ if type(colordata) == "table" then
+ colordata = { unpack(colordata) } -- copy
+ end
+ currentpage[#currentpage+1] = {
+ type = 'show',
+ string = s,
+ fontname = fontname,
+ adjust = nil,
+ x = position[1],
+ y = position[2],
+ encoding = stringencoding,
+ fontmatrix = stringmatrix,
+ matrix = truematrix,
+ colortype = colortype,
+ color = colordata,
+ }
+ -- todo: update currentpoint, needing 'stringwidth'
+end
+
+function operators.show()
+ local s = pop_opstack()
+ if not s then
+ return ps_error('stackunderflow')
+ end
+ if s[1] ~= 'string' then
+ return ps_error('typecheck')
+ end
+ if #gsstate.position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ if not gsstate.font then
+ return ps_error('invalidfont')
+ end
+ local fontdict = get_VM(gsstate.font)
+ if fontdict.access == "noaccess" then
+ return ps_error('invalidaccess')
+ end
+ if not checkfont(fontdict.dict) then
+ return ps_error('invalidfont')
+ end
+ do_show(fontdict,get_VM(s[4]))
+end
+
+
+function operators.kshow()
+ local a = pop_opstack()
+ local b = pop_opstack()
+ if not a then
+ return ps_error('stackunderflow')
+ end
+ if b[1] ~= "array" and b[3] == 'executable' then
+ return ps_error('typecheck')
+ end
+ if b[2] == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ if not a[1] == 'string' then
+ return ps_error('typecheck')
+ end
+ if a[2] == "execute-only" or a[2] == 'noaccess' then
+ return ps_error('invalidaccess')
+ end
+ local fontdict = get_VM(gsstate.font)
+ if fontdict.access == "noaccess" then
+ return ps_error('invalidaccess')
+ end
+ if #gsstate.position == 0 then
+ return ps_error('nocurrentpoint')
+ end
+ -- ok, that were the errors
+ push_execstack { '.exit', 'unlimited', 'literal', false }
+ local curstack = execstackptr
+ if a[6] == 0 then
+ return true
+ end
+ b[7] = 'i'
+ local thestring = get_VM(a[4])
+ local v = sub(thestring,1,1)
+ thestring = sub(thestring,2,-1)
+ do_show(fontdict,v)
+ for w in gmatch(thestring,".") do
+ if stopped then
+ stopped = false
+ return false
+ end
+ push_opstack { 'integer', 'unlimited', 'literal', byte(v) }
+ push_opstack { 'integer', 'unlimited', 'literal', byte(w) }
+ b[5] = 1
+ push_execstack(b)
+ while curstack < execstackptr do
+ do_exec()
+ end
+ local entry = execstack[execstackptr]
+ if entry[1] == '.exit' and entry[4] == true then
+ pop_execstack()
+ return true;
+ end
+ do_show(fontdict,w)
+ v = w
+ end
+ return true
+end
+
+local the_standardencoding = {
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand',
+ 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma',
+ 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four',
+ 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less',
+ 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash',
+ 'bracketright', 'asciicircum', 'underscore', 'quoteleft', 'a', 'b',
+ 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar',
+ 'braceright', 'asciitilde', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', 'exclamdown', 'cent', 'sterling', 'fraction', 'yen',
+ 'florin', 'section', 'currency', 'quotesingle', 'quotedblleft',
+ 'guillemotleft', 'guilsinglleft', 'guilsinglright', 'fi', 'fl',
+ '.notdef', 'endash', 'dagger', 'daggerdbl', 'periodcentered', '.notdef',
+ 'paragraph', 'bullet', 'quotesinglbase', 'quotedblbase',
+ 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand', '.notdef',
+ 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 'macron',
+ 'breve', 'dotaccent', 'dieresis', '.notdef', 'ring', 'cedilla',
+ '.notdef', 'hungarumlaut', 'ogonek', 'caron', 'emdash', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ '.notdef', '.notdef', '.notdef', 'AE', '.notdef', 'ordfeminine',
+ '.notdef', '.notdef', '.notdef', '.notdef', 'Lslash', 'Oslash', 'OE',
+ 'ordmasculine', '.notdef', '.notdef', '.notdef', '.notdef', '.notdef',
+ 'ae', '.notdef', '.notdef', '.notdef', 'dotlessi', '.notdef',
+ '.notdef', 'lslash', 'oslash', 'oe', 'germandbls', '.notdef',
+ '.notdef', '.notdef', '.notdef'
+}
+
+local function standardencoding()
+ local a = { }
+ for i=1,#the_standardencoding do
+ a[i] = { 'name', 'unlimited', 'literal', add_VM(the_standardencoding[i]) }
+ end
+ return a
+end
+
+-- Font cache operators
+--
+-- -cachestatus -setcachedevice -setcharwidth -setcachelimit
+
+-- userdict (initially empty)
+
+local systemdict
+local userdict
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ systemdict = nil
+ else
+ dictstackptr = dictstackptr + 1
+ dictstack[dictstackptr] = add_VM {
+ access = 'unlimited',
+ maxsize = MAX_INTEGER,
+ size = 0,
+ dict = { },
+ }
+ if directvm then
+ systemdict = dictstack[dictstackptr]
+ else
+ systemdict = dictstackptr
+ end
+ end
+end
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ userdict = nil
+ else
+ dictstackptr = dictstackptr + 1
+ dictstack[dictstackptr] = add_VM {
+ access = 'unlimited',
+ maxsize = MAX_INTEGER,
+ size = 0,
+ dict = { },
+ }
+ if directvm then
+ userdict = dictstack[dictstackptr]
+ else
+ userdict = dictstackptr
+ end
+ end
+end
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ -- already done
+ else
+ local dict = {
+ ['$error'] = { 'dict', 'unlimited', 'literal', dicterror },
+ ['['] = { 'operator', 'unlimited', 'executable', operators.beginarray, '[' },
+ [']'] = { 'operator', 'unlimited', 'executable', operators.endarray, ']' },
+ -- ['='] = { 'operator', 'unlimited', 'executable', operators.EQ, '=' },
+ ['=='] = { 'operator', 'unlimited', 'executable', operators.equal, '==' },
+ ['abs'] = { 'operator', 'unlimited', 'executable', operators.abs, 'abs' },
+ ['add'] = { 'operator', 'unlimited', 'executable', operators.add, 'add' },
+ ['aload'] = { 'operator', 'unlimited', 'executable', operators.aload, 'aload' },
+ ['anchorsearch'] = { 'operator', 'unlimited', 'executable', operators.anchorsearch, 'anchorsearch' },
+ ['and'] = { 'operator', 'unlimited', 'executable', operators["and"], 'and' },
+ ['arc'] = { 'operator', 'unlimited', 'executable', operators.arc, 'arc' },
+ ['arcn'] = { 'operator', 'unlimited', 'executable', operators.arcn, 'arcn' },
+ ['arcto'] = { 'operator', 'unlimited', 'executable', operators.arcto, 'arcto' },
+ ['array'] = { 'operator', 'unlimited', 'executable', operators.array, 'array' },
+ ['astore'] = { 'operator', 'unlimited', 'executable', operators.astore, 'astore' },
+ ['atan'] = { 'operator', 'unlimited', 'executable', operators.atan, 'atan' },
+ ['banddevice'] = { 'operator', 'unlimited', 'executable', operators.banddevice, 'banddevice' },
+ ['bind'] = { 'operator', 'unlimited', 'executable', operators.bind, 'bind' },
+ ['bitshift'] = { 'operator', 'unlimited', 'executable', operators.bitshift, 'bitshift' },
+ ['begin'] = { 'operator', 'unlimited', 'executable', operators.begin, 'begin' },
+ ['bytesavailable'] = { 'operator', 'unlimited', 'executable', operators.bytesavailable, 'bytesavailable' },
+ ['ceiling'] = { 'operator', 'unlimited', 'executable', operators.ceiling, 'ceiling' },
+ ['clear'] = { 'operator', 'unlimited', 'executable', operators.clear, 'clear' },
+ ['cleartomark'] = { 'operator', 'unlimited', 'executable', operators.cleartomark, 'cleartomark' },
+ ['clip'] = { 'operator', 'unlimited', 'executable', operators.clip, 'clip' },
+ ['clippath'] = { 'operator', 'unlimited', 'executable', operators.clippath, 'clippath' },
+ ['closefile'] = { 'operator', 'unlimited', 'executable', operators.closefile, 'closefile' },
+ ['closepath'] = { 'operator', 'unlimited', 'executable', operators.closepath, 'closepath' },
+ ['concat'] = { 'operator', 'unlimited', 'executable', operators.concat, 'concat' },
+ ['concatmatrix'] = { 'operator', 'unlimited', 'executable', operators.concatmatrix, 'concatmatrix' },
+ ['copy'] = { 'operator', 'unlimited', 'executable', operators.copy, 'copy' },
+ ['copypage'] = { 'operator', 'unlimited', 'executable', operators.copypage, 'copypage' },
+ ['cos'] = { 'operator', 'unlimited', 'executable', operators.cos, 'cos' },
+ ['count'] = { 'operator', 'unlimited', 'executable', operators.count, 'count' },
+ ['countdictstack'] = { 'operator', 'unlimited', 'executable', operators.countdictstack, 'countdictstack' },
+ ['countexecstack'] = { 'operator', 'unlimited', 'executable', operators.countexecstack, 'countexecstack' },
+ ['counttomark'] = { 'operator', 'unlimited', 'executable', operators.counttomark, 'counttomark' },
+ ['currentdash'] = { 'operator', 'unlimited', 'executable', operators.currentdash, 'currentdash' },
+ ['currentdict'] = { 'operator', 'unlimited', 'executable', operators.currentdict, 'currentdict' },
+ ['currentfile'] = { 'operator', 'unlimited', 'executable', operators.currentfile, 'currentfile' },
+ ['currentflat'] = { 'operator', 'unlimited', 'executable', operators.currentflat, 'currentflat' },
+ ['currentfont'] = { 'operator', 'unlimited', 'executable', operators.currentfont, 'currentfont' },
+ ['currentgray'] = { 'operator', 'unlimited', 'executable', operators.currentgray, 'currentgray' },
+ ['currenthsbcolor'] = { 'operator', 'unlimited', 'executable', operators.currenthsbcolor, 'currenthsbcolor' },
+ ['currentlinecap'] = { 'operator', 'unlimited', 'executable', operators.currentlinecap, 'currentlinecap' },
+ ['currentlinejoin'] = { 'operator', 'unlimited', 'executable', operators.currentlinejoin, 'currentlinejoin' },
+ ['currentlinewidth'] = { 'operator', 'unlimited', 'executable', operators.currentlinewidth, 'currentlinewidth' },
+ ['currentmatrix'] = { 'operator', 'unlimited', 'executable', operators.currentmatrix, 'currentmatrix' },
+ ['currentmiterlimit'] = { 'operator', 'unlimited', 'executable', operators.currentmiterlimit, 'currentmiterlimit' },
+ ['currentpoint'] = { 'operator', 'unlimited', 'executable', operators.currentpoint, 'currentpoint' },
+ ['currentrgbcolor'] = { 'operator', 'unlimited', 'executable', operators.currentrgbcolor, 'currentrgbcolor' },
+ ['currentcmykcolor'] = { 'operator', 'unlimited', 'executable', operators.currentcmykcolor, 'currentcmykcolor' },
+ ['currentscreen'] = { 'operator', 'unlimited', 'executable', operators.currentscreen, 'currentscreen' },
+ ['currenttransfer'] = { 'operator', 'unlimited', 'executable', operators.currenttransfer, 'currenttransfer' },
+ ['curveto'] = { 'operator', 'unlimited', 'executable', operators.curveto, 'curveto' },
+ ['cvi'] = { 'operator', 'unlimited', 'executable', operators.cvi, 'cvi' },
+ ['cvlit'] = { 'operator', 'unlimited', 'executable', operators.cvlit, 'cvlit' },
+ ['cvn'] = { 'operator', 'unlimited', 'executable', operators.cvn, 'cvn' },
+ ['cvr'] = { 'operator', 'unlimited', 'executable', operators.cvr, 'cvr' },
+ ['cvrs'] = { 'operator', 'unlimited', 'executable', operators.cvrs, 'cvrs' },
+ ['cvs'] = { 'operator', 'unlimited', 'executable', operators.cvs, 'cvs' },
+ ['cvx'] = { 'operator', 'unlimited', 'executable', operators.cvx, 'cvx' },
+ ['def'] = { 'operator', 'unlimited', 'executable', operators.def, 'def' },
+ ['definefont'] = { 'operator', 'unlimited', 'executable', operators.definefont, 'definefont' },
+ ['dict'] = { 'operator', 'unlimited', 'executable', operators.dict, 'dict' },
+ ['dictstack'] = { 'operator', 'unlimited', 'executable', operators.dictstack, 'dictstack' },
+ ['div'] = { 'operator', 'unlimited', 'executable', operators.div, 'div' },
+ ['dtransform'] = { 'operator', 'unlimited', 'executable', operators.dtransform, 'dtransform' },
+ ['dup'] = { 'operator', 'unlimited', 'executable', operators.dup, 'dup' },
+ ['echo'] = { 'operator', 'unlimited', 'executable', operators.echo, 'echo' },
+ ['end'] = { 'operator', 'unlimited', 'executable', operators["end"], 'end' },
+ ['eoclip'] = { 'operator', 'unlimited', 'executable', operators.eoclip, 'eoclip' },
+ ['eofill'] = { 'operator', 'unlimited', 'executable', operators.eofill, 'eofill' },
+ ['eq'] = { 'operator', 'unlimited', 'executable', operators.eq, 'eq' },
+ ['errordict'] = { 'dict', 'unlimited', 'literal', errordict },
+ ['exch'] = { 'operator', 'unlimited', 'executable', operators.exch, 'exch' },
+ ['exec'] = { 'operator', 'unlimited', 'executable', operators.exec, 'exec' },
+ ['execstack'] = { 'operator', 'unlimited', 'executable', operators.execstack, 'execstack' },
+ ['executeonly'] = { 'operator', 'unlimited', 'executable', operators.executeonly, 'executeonly' },
+ ['exit'] = { 'operator', 'unlimited', 'executable', operators.exit, 'exit' },
+ ['exp'] = { 'operator', 'unlimited', 'executable', operators.exp, 'exp' },
+ ['false'] = { 'boolean', 'unlimited', 'literal', false },
+ ['file'] = { 'operator', 'unlimited', 'executable', operators.file, 'file' },
+ ['fill'] = { 'operator', 'unlimited', 'executable', operators.fill, 'fill' },
+ ['findfont'] = { 'operator', 'unlimited', 'executable', operators.findfont, 'findfont' },
+ ['FontDirectory'] = { 'dict', 'unlimited', 'literal', escrito['FontDirectory'] },
+ ['flattenpath'] = { 'operator', 'unlimited', 'executable', operators.flattenpath, 'flattenpath' },
+ ['floor'] = { 'operator', 'unlimited', 'executable', operators.floor, 'floor' },
+ ['flush'] = { 'operator', 'unlimited', 'executable', operators.flush, 'flush' },
+ ['flushfile'] = { 'operator', 'unlimited', 'executable', operators.flushfile, 'flushfile' },
+ ['for'] = { 'operator', 'unlimited', 'executable', operators["for"], 'for' },
+ ['forall'] = { 'operator', 'unlimited', 'executable', operators.forall, 'forall' },
+ ['framedevice'] = { 'operator', 'unlimited', 'executable', operators.framedevice, 'framedevice' },
+ ['ge'] = { 'operator', 'unlimited', 'executable', operators.ge, 'ge' },
+ ['get'] = { 'operator', 'unlimited', 'executable', operators.get, 'get' },
+ ['getinterval'] = { 'operator', 'unlimited', 'executable', operators.getinterval, 'getinterval' },
+ ['grestore'] = { 'operator', 'unlimited', 'executable', operators.grestore, 'grestore' },
+ ['grestoreall'] = { 'operator', 'unlimited', 'executable', operators.grestoreall, 'grestoreall' },
+ ['gsave'] = { 'operator', 'unlimited', 'executable', operators.gsave, 'gsave' },
+ ['gt'] = { 'operator', 'unlimited', 'executable', operators.gt, 'gt' },
+ ['identmatrix'] = { 'operator', 'unlimited', 'executable', operators.identmatrix, 'identmatrix' },
+ ['idiv'] = { 'operator', 'unlimited', 'executable', operators.idiv, 'idiv' },
+ ['if'] = { 'operator', 'unlimited', 'executable', operators["if"], 'if' },
+ ['ifelse'] = { 'operator', 'unlimited', 'executable', operators.ifelse, 'ifelse' },
+ ['index'] = { 'operator', 'unlimited', 'executable', operators.index, 'index' },
+ ['initclip'] = { 'operator', 'unlimited', 'executable', operators.initclip, 'initclip' },
+ ['initgraphics'] = { 'operator', 'unlimited', 'executable', operators.initgraphics, 'initgraphics' },
+ ['initmatrix'] = { 'operator', 'unlimited', 'executable', operators.initmatrix, 'initmatrix' },
+ ['invertmatrix'] = { 'operator', 'unlimited', 'executable', operators.invertmatrix, 'invertmatrix' },
+ ['idtransform'] = { 'operator', 'unlimited', 'executable', operators.idtransform, 'idtransform' },
+ ['itransform'] = { 'operator', 'unlimited', 'executable', operators.itransform, 'itransform' },
+ ['known'] = { 'operator', 'unlimited', 'executable', operators.known, 'known' },
+ ['kshow'] = { 'operator', 'unlimited', 'executable', operators.kshow, 'kshow' },
+ ['le'] = { 'operator', 'unlimited', 'executable', operators.le, 'le' },
+ ['length'] = { 'operator', 'unlimited', 'executable', operators.length, 'length' },
+ ['lineto'] = { 'operator', 'unlimited', 'executable', operators.lineto, 'lineto' },
+ ['ln'] = { 'operator', 'unlimited', 'executable', operators.ln, 'ln' },
+ ['load'] = { 'operator', 'unlimited', 'executable', operators.load, 'load' },
+ ['log'] = { 'operator', 'unlimited', 'executable', operators.log, 'log' },
+ ['loop'] = { 'operator', 'unlimited', 'executable', operators.loop, 'loop' },
+ ['lt'] = { 'operator', 'unlimited', 'executable', operators.lt, 'lt' },
+ ['makefont'] = { 'operator', 'unlimited', 'executable', operators.makefont, 'makefont' },
+ ['mark'] = { 'operator', 'unlimited', 'executable', operators.mark, 'mark' },
+ ['matrix'] = { 'operator', 'unlimited', 'executable', operators.matrix, 'matrix' },
+ ['maxlength'] = { 'operator', 'unlimited', 'executable', operators.maxlength, 'maxlength' },
+ ['mod'] = { 'operator', 'unlimited', 'executable', operators.mod, 'mod' },
+ ['moveto'] = { 'operator', 'unlimited', 'executable', operators.moveto, 'moveto' },
+ ['mul'] = { 'operator', 'unlimited', 'executable', operators.mul, 'mul' },
+ ['ne'] = { 'operator', 'unlimited', 'executable', operators.ne, 'ne' },
+ ['neg'] = { 'operator', 'unlimited', 'executable', operators.neg, 'neg' },
+ ['newpath'] = { 'operator', 'unlimited', 'executable', operators.newpath, 'newpath' },
+ ['noaccess'] = { 'operator', 'unlimited', 'executable', operators.noaccess, 'noaccess' },
+ ['not'] = { 'operator', 'unlimited', 'executable', operators["not"], 'not' },
+ ['null'] = { 'operator', 'unlimited', 'executable', operators.null, 'null' },
+ ['or'] = { 'operator', 'unlimited', 'executable', operators["or"], 'or' },
+ ['pop'] = { 'operator', 'unlimited', 'executable', operators.pop, 'pop' },
+ ['print'] = { 'operator', 'unlimited', 'executable', operators.print, 'print' },
+ ['pstack'] = { 'operator', 'unlimited', 'executable', operators.pstack, 'pstack' },
+ ['put'] = { 'operator', 'unlimited', 'executable', operators.put, 'put' },
+ ['putinterval'] = { 'operator', 'unlimited', 'executable', operators.putinterval, 'putinterval' },
+ ['quit'] = { 'operator', 'unlimited', 'executable', operators.quit, 'quit' },
+ ['rand'] = { 'operator', 'unlimited', 'executable', operators.rand, 'rand' },
+ ['rcheck'] = { 'operator', 'unlimited', 'executable', operators.rcheck, 'rcheck' },
+ ['rcurveto'] = { 'operator', 'unlimited', 'executable', operators.rcurveto, 'rcurveto' },
+ ['read'] = { 'operator', 'unlimited', 'executable', operators.read, 'read' },
+ ['readhexstring'] = { 'operator', 'unlimited', 'executable', operators.readhexstring, 'readhexstring' },
+ ['readline'] = { 'operator', 'unlimited', 'executable', operators.readline, 'readline' },
+ ['readonly'] = { 'operator', 'unlimited', 'executable', operators.readonly, 'readonly' },
+ ['renderbands'] = { 'operator', 'unlimited', 'executable', operators.renderbands, 'renderbands' },
+ ['repeat'] = { 'operator', 'unlimited', 'executable', operators["repeat"], 'repeat' },
+ ['resetfile'] = { 'operator', 'unlimited', 'executable', operators.resetfile, 'resetfile' },
+ ['restore'] = { 'operator', 'unlimited', 'executable', operators.restore, 'restore' },
+ ['rlineto'] = { 'operator', 'unlimited', 'executable', operators.rlineto, 'rlineto' },
+ ['rmoveto'] = { 'operator', 'unlimited', 'executable', operators.rmoveto, 'rmoveto' },
+ ['roll'] = { 'operator', 'unlimited', 'executable', operators.roll, 'roll' },
+ ['rotate'] = { 'operator', 'unlimited', 'executable', operators.rotate, 'rotate' },
+ ['round'] = { 'operator', 'unlimited', 'executable', operators.round, 'round' },
+ ['rrand'] = { 'operator', 'unlimited', 'executable', operators.rrand, 'rrand' },
+ ['run'] = { 'operator', 'unlimited', 'executable', operators.run, 'run' },
+ ['save'] = { 'operator', 'unlimited', 'executable', operators.save, 'save' },
+ ['scale'] = { 'operator', 'unlimited', 'executable', operators.scale, 'scale' },
+ ['scalefont'] = { 'operator', 'unlimited', 'executable', operators.scalefont, 'scalefont' },
+ ['search'] = { 'operator', 'unlimited', 'executable', operators.search, 'search' },
+ ['setdash'] = { 'operator', 'unlimited', 'executable', operators.setdash, 'setdash' },
+ ['setflat'] = { 'operator', 'unlimited', 'executable', operators.setflat, 'setflat' },
+ ['setfont'] = { 'operator', 'unlimited', 'executable', operators.setfont, 'setfont' },
+ ['setgray'] = { 'operator', 'unlimited', 'executable', operators.setgray, 'setgray' },
+ ['sethsbcolor'] = { 'operator', 'unlimited', 'executable', operators.sethsbcolor, 'sethsbcolor' },
+ ['setlinecap'] = { 'operator', 'unlimited', 'executable', operators.setlinecap, 'setlinecap' },
+ ['setlinejoin'] = { 'operator', 'unlimited', 'executable', operators.setlinejoin, 'setlinejoin' },
+ ['setlinewidth'] = { 'operator', 'unlimited', 'executable', operators.setlinewidth, 'setlinewidth' },
+ ['setmatrix'] = { 'operator', 'unlimited', 'executable', operators.setmatrix, 'setmatrix' },
+ ['setmiterlimit'] = { 'operator', 'unlimited', 'executable', operators.setmiterlimit, 'setmiterlimit' },
+ ['setrgbcolor'] = { 'operator', 'unlimited', 'executable', operators.setrgbcolor, 'setrgbcolor' },
+ ['setcmykcolor'] = { 'operator', 'unlimited', 'executable', operators.setcmykcolor, 'setcmykcolor' },
+ ['setscreen'] = { 'operator', 'unlimited', 'executable', operators.setscreen, 'setscreen' },
+ ['settransfer'] = { 'operator', 'unlimited', 'executable', operators.settransfer, 'settransfer' },
+ ['show'] = { 'operator', 'unlimited', 'executable', operators.show, 'show' },
+ ['showpage'] = { 'operator', 'unlimited', 'executable', operators.showpage, 'showpage' },
+ ['sin'] = { 'operator', 'unlimited', 'executable', operators.sin, 'sin' },
+ ['sqrt'] = { 'operator', 'unlimited', 'executable', operators.sqrt, 'sqrt' },
+ ['srand'] = { 'operator', 'unlimited', 'executable', operators.srand, 'srand' },
+ ['stack'] = { 'operator', 'unlimited', 'executable', operators.stack, 'stack' },
+ ['start'] = { 'operator', 'unlimited', 'executable', operators.start, 'start' },
+ ['StandardEncoding'] = { 'array', 'unlimited', 'literal', add_VM(standardencoding()), 256, 256 },
+ ['status'] = { 'operator', 'unlimited', 'executable', operators.status, 'status' },
+ ['stop'] = { 'operator', 'unlimited', 'executable', operators.stop, 'stop' },
+ ['stopped'] = { 'operator', 'unlimited', 'executable', operators.stopped, 'stopped' },
+ ['store'] = { 'operator', 'unlimited', 'executable', operators.store, 'store' },
+ ['string'] = { 'operator', 'unlimited', 'executable', operators.string, 'string' },
+ ['stroke'] = { 'operator', 'unlimited', 'executable', operators.stroke, 'stroke' },
+ ['sub'] = { 'operator', 'unlimited', 'executable', operators.sub, 'sub' },
+ ['systemdict'] = { 'dict', 'unlimited', 'literal', systemdict },
+ ['token'] = { 'operator', 'unlimited', 'executable', operators.token, 'token' },
+ ['translate'] = { 'operator', 'unlimited', 'executable', operators.translate, 'translate' },
+ ['transform'] = { 'operator', 'unlimited', 'executable', operators.transform, 'transform' },
+ ['true'] = { 'boolean', 'unlimited', 'literal', true },
+ ['truncate'] = { 'operator', 'unlimited', 'executable', operators.truncate, 'truncate' },
+ ['type'] = { 'operator', 'unlimited', 'executable', operators.type, 'type' },
+ ['userdict'] = { 'dict', 'unlimited', 'literal', userdict },
+ ['usertime'] = { 'operator', 'unlimited', 'executable', operators.usertime, 'usertime' },
+ ['version'] = { 'operator', 'unlimited', 'executable', operators.version, 'version' },
+ ['vmstatus'] = { 'operator', 'unlimited', 'executable', operators.vmstatus, 'vmstatus' },
+ ['wcheck'] = { 'operator', 'unlimited', 'executable', operators.wcheck, 'wcheck' },
+ ['where'] = { 'operator', 'unlimited', 'executable', operators.where, 'where' },
+ ['write'] = { 'operator', 'unlimited', 'executable', operators.write, 'write' },
+ ['writehexstring'] = { 'operator', 'unlimited', 'executable', operators.writehexstring, 'writehexstring' },
+ ['writestring'] = { 'operator', 'unlimited', 'executable', operators.writestring, 'writestring' },
+ ['xcheck'] = { 'operator', 'unlimited', 'executable', operators.xcheck, 'xcheck' },
+ ['xor'] = { 'operator', 'unlimited', 'executable', operators.xor, 'xor' },
+ }
+ if directvm then
+ systemdict.dict = dict
+ else
+ VM[dictstack[systemdict]].dict = dict
+ end
+ end
+end
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ dicterror = nil
+ errordict = nil
+ else
+ dicterror = add_VM {
+ access = 'unlimited',
+ size = 1,
+ maxsize = 40,
+ dict = {
+ newerror = { 'boolean', 'unlimited', 'literal', false }
+ },
+ }
+ --
+ errordict = add_VM {
+ access = 'unlimited',
+ size = 0,
+ maxsize = 40,
+ dict = { },
+ }
+ --
+ local d
+ if directvm then
+ d = systemdict.dict
+ else
+ d = VM[dictstack[systemdict]].dict
+ end
+ -- still needed ?
+ d['errordict'] = { 'dict', 'unlimited', 'literal', errordict }
+ d['systemdict'] = { 'dict', 'unlimited', 'literal', systemdict }
+ d['userdict'] = { 'dict', 'unlimited', 'literal', userdict }
+ d['$error'] = { 'dict', 'unlimited', 'literal', dicterror }
+ end
+end
+
+-- What follows is the main interpreter, with the tokenizer first
+
+-- procedure scanning stack for the tokenizer
+
+local procstack
+local procstackptr
+
+initializers[#initializers+1] = function(reset)
+ if reset then
+ procstack = nil
+ procstackptr = nil
+ else
+ procstack = { }
+ procstackptr = 0
+ end
+end
+
+-- lpeg parser for tokenization
+
+do
+
+ local function push(v)
+ if procstackptr > 0 then
+ local top = procstack[procstackptr]
+ if top then
+ top[#top+1] = v
+ else
+ procstack[procstackptr] = { v }
+ end
+ return false
+ else
+ push_execstack(v)
+ return true
+ end
+ end
+
+ local function start()
+ procstackptr = procstackptr + 1
+ return true
+ end
+
+ local function stop()
+ local v = procstack[procstackptr]
+ procstack[procstackptr] = { }
+ procstackptr = procstackptr - 1
+ if push {'array', 'unlimited', 'executable', add_VM(v), 1, #v, 'd' } then
+ return true
+ end
+ end
+
+ local function hexify(a)
+ return char(tonumber(a,16))
+ end
+
+ local function octify(a)
+ return char(tonumber(a,8))
+ end
+
+ local function radixed(base,value)
+ base = tonumber(base)
+ if base > 36 or base < 2 then
+ return nil
+ end
+ value = tonumber(value,base)
+ if not value then
+ return "error", false
+ elseif value > MAX_INT then
+ return "integer", value
+ else
+ return "real", value
+ end
+ end
+
+ local space = S(' ')
+ local spacing = S(' \t\r\n\f')
+ local sign = S('+-')^-1
+ local digit = R('09')
+ local period = P('.')
+ local letters = R('!~') - S('[]<>{}()%')
+ local hexdigit = R('09','af','AF')
+ local radixdigit = R('09','az','AZ')
+
+ local p_integer = (sign * digit^1 * #(1-letters)) / tonumber
+ local p_real = ((sign * digit^0 * period * digit^0 + period * digit^1) * (S('eE') * sign * digit^1)^-1 * #(1-letters)) / tonumber
+ local p_literal = Cs(P("/")/"" * letters^1 * letters^0)
+ local p_symbol = C(letters^1 * letters^0)
+ ----- p_radixed = C(digit^1) * P("#") * C(radixdigit^1) * #(1-letters) / radixed-- weird #() here
+ local p_radixed = C(digit^1) * P("#") * C(radixdigit^1) / radixed
+ local p_unhexed = P("<") * Cs(((C(hexdigit*hexdigit) * Cc(16))/tonumber/char+spacing/"")^0) * P(">")
+ local p_comment = P('%') * (1 - S('\r\n'))^0 * Cc(true)
+ local p_bounding = P('%%BoundingBox:') * Ct((space^0 * p_integer)^4) * (1 - S('\r\n'))^0
+ local p_lbrace = C("{")
+ local p_rbrace = C("}")
+ local p_lbracket = C("[")
+ local p_rbracket = C("]")
+ local p_finish = Cc(false)
+
+ local p_string =
+ P("(")
+ * Cs( P {
+ (
+ (1 - S("()\\"))^1
+ + P("\\")/"" * (
+ (C(digit *digit * digit) * Cc(8)) / tonumber / char
+ + P("n") / "\n" + P("r") / "\r" + P("t") / "\t"
+ + P("b") / "\b" + P("f") / "\f" + P("\\") / "\\"
+ + 1
+ )
+ + P("(") * V(1) * P(")")
+ )^0
+ })
+ * P(")")
+
+ -- inspect(lpegmatch(p_radixed,"10#123"))
+ -- inspect(lpegmatch(p_unhexed,"<A2B3 C3>"))
+ -- inspect(lpegmatch(p_string,[[(foo(bar \124\125 \( bar\n bar\\bar))]]))
+
+ local p_unhexed = Cc('string') * p_unhexed
+ local p_string = Cc('string') * p_string
+ local p_array_start = Cc('name') * p_lbracket
+ local p_array_stop = Cc('name') * p_rbracket
+ local p_exec_start = Cc('start') * p_lbrace
+ local p_exec_stop = Cc('stop') * p_rbrace
+ local p_integer = Cc('integer') * p_integer
+ local p_real = Cc('real') * p_real
+ local p_radixed = p_radixed
+ local p_symbol = Cc('name') * p_symbol
+ local p_literal = Cc('literal') * p_literal
+ local p_comment = Cc('comment') * p_comment
+ local p_bounding = Cc('bounding') * p_bounding
+ local p_finish = Cc("eof") * p_finish
+ local p_whitespace = spacing^0
+
+ local tokens = p_whitespace
+ * (
+ p_bounding
+ + p_comment
+ + p_string
+ + p_unhexed
+ + p_array_start
+ + p_array_stop
+ + p_exec_start
+ + p_exec_stop
+ + p_real
+ + p_radixed
+ + p_integer
+ + p_literal
+ + p_symbol
+ + p_finish
+ )^-1
+ * Cp()
+
+ -- we can do push etc in the lpeg but the call is not faster than the check
+ -- and this stays closer to the original
+
+ local function tokenize()
+ local object = execstack[execstackptr]
+ local sequence = object[4]
+ local position = object[5]
+ local length = object[6]
+ local tokentype = nil
+ local value = nil
+ while position < length do
+ tokentype, value, position = lpegmatch(tokens,get_VM(sequence),position)
+ if not position then
+ return false
+ elseif position >= length then
+ pop_execstack()
+ else
+ object[5] = position
+ end
+ if not value then
+ return false -- handle_error('syntaxerror')
+ elseif tokentype == 'integer' or tokentype == 'real' then
+ if push { tokentype, 'unlimited', 'literal', value } then
+ return true
+ end
+ elseif tokentype == 'name' then
+ if push { 'name', 'unlimited', 'executable', add_VM(value) } then
+ return true
+ end
+ elseif tokentype == 'literal' then
+ if push { 'name', 'unlimited', 'literal', add_VM(value) } then
+ return true
+ end
+ elseif tokentype == 'string' then
+ if push { 'string', 'unlimited', 'literal', add_VM(value), 1, #value } then
+ return true
+ end
+ elseif tokentype == 'start' then
+ if start() then
+ -- stay
+ end
+ elseif tokentype == 'stop' then
+ if stop() then
+ return true
+ end
+ elseif tokentype == 'bounding' then
+ specials.boundingbox = value
+ end
+ end
+ return position >= length
+ end
+
+ -- the exec stack can contain a limited amount of interesting item types
+ -- to be handled by next_object:
+ -- executable arrays (procedures)
+ -- executable strings
+ -- executable files
+
+ next_object = function()
+ if execstackptr == 0 then
+ return nil
+ end
+ local object = execstack[execstackptr]
+ if not object then
+ return nil
+ end
+ local otyp = object[1]
+ local exec = object[3] == 'executable'
+ if not exec then
+ return pop_execstack()
+ elseif otyp == 'array' then
+ if object[7] == 'd' then
+ return pop_execstack()
+ else
+ local proc = get_VM(object[4])
+ local o = object[5]
+ local val = proc[o]
+ if o >= #proc then
+ object[5] = 1
+ pop_execstack()
+ else
+ object[5] = o + 1
+ end
+ return val
+ end
+ elseif otyp == 'string' then
+ if not tokenize() then
+ report("tokenizer failed on string")
+ return nil
+ else
+ return next_object() -- recurse
+ end
+ elseif otyp == 'file' then
+ if object[4] == 0 then
+ report('sorry, interactive mode is not supported')
+ end
+ if not tokenize() then
+ report("tokenizer failed on file")
+ return nil
+ else
+ return next_object() -- recurse
+ end
+ else
+ return pop_execstack()
+ end
+ end
+
+-- The main execution control function
+
+ local detail = false -- much faster
+
+ local report_exec = logs.reporter("escrito","exec")
+
+ do_exec = function() -- already a local
+ local ret
+ local savedopstack = detail and copy_opstack()
+ local object = next_object()
+ if not object then
+ return false
+ end
+ local otyp = object[1]
+ if DEBUG then
+ if otyp == 'operator' then
+ report_exec("%s %s %s",otyp,object[3],object[5])
+ elseif otyp == 'dict' then
+ local d = get_VM(object[4])
+ report_exec("%s %s <%s:%s>",otyp,object[3],d.size or '',d.maxsize or '')
+ elseif otyp == 'array' or otyp == 'file' or otyp == 'save' then
+ report_exec("%s <%s:%s>",object[3],object[5] or '',object[6] or '')
+ elseif otyp == 'string' or otyp == 'name' then
+ report_exec("%s %s %s",otyp,object[3],get_VM(object[4]))
+ else
+ report_exec("%s %s %s",otyp,object[3],tostring(object[4]))
+ end
+ end
+ if otyp == 'real' or otyp == 'integer' or otyp == 'boolean' or otyp == 'mark' or otyp == 'save' or otyp == 'font' then
+ push_opstack(object)
+ elseif otyp == '.stopped' then
+ -- when .stopped is seen here, stop was never called
+ push_opstack { 'boolean', 'unlimited', 'executable', false}
+ elseif otyp == '.exit' then
+ -- when .exit is seen here, exit was never called
+ elseif otyp == 'array' then
+ if object[2] == 'noaccess' then
+ escrito.errorname = 'noaccess'
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'string' then
+ if object[2] == 'noaccess' then
+ escrito.errorname = 'noaccess'
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'dict' then
+ local dict = get_VM(object[4])
+ if dict.access == 'noaccess' then
+ escrito.errorname = 'noaccess'
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'file' then
+ if object[2] == 'noaccess' then
+ errorname = 'noaccess'
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'null' then
+ push_opstack(object)
+ elseif otyp == 'operator' then
+ if object[3]=='executable' then
+ ret, escrito.errorname = object[4]()
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'save' then
+ -- todo
+ elseif otyp == 'name' then
+ if object[3] == 'executable' then
+ local v = lookup(get_VM(object[4]))
+ if not v then
+ if escrito.errorname then
+ -- doesn't work, needs thinking
+ error ("recursive error detected inside '" .. escrito.errorname .. "'")
+ end
+ escrito.errorname = 'undefined'
+ else
+ if DEBUG then
+ local vt = v[1]
+ if vt == 'operator' then
+ print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. v[5])
+ elseif vt == 'dict' or vt == 'array' or vt == 'file' or vt == 'save' then
+ print ('exec2: ' .. vt .. ' ' .. v[3] .. ' <'.. (v[5] or '') .. '>')
+ elseif vt == 'string' or vt == 'name' then
+ print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. get_VM(v[4]))
+ else
+ print ('exec2: ' .. vt .. ' ' .. v[3] .. ' '.. tostring(v[4]))
+ end
+ end
+ push_execstack(v)
+ end
+ else
+ push_opstack(object)
+ end
+ elseif otyp == 'null' then
+ -- do nothing
+ elseif otyp == 'array' then
+ push_opstack(object)
+ end
+
+ if escrito.errorname then
+ if savedopstack then
+ local v = lookup_error(escrito.errorname)
+ if not v then
+ print("unknown error handler for '" .. escrito.errorname .. "', quitting")
+ return false
+ else
+ set_opstack(savedopstack)
+ push_opstack { otyp, object[2], "literal", object[4], object[5], object[6], object[7] }
+ push_opstack { 'string','unlimited','literal',add_VM(escrito.errorname), 1 }
+ push_execstack(v)
+ end
+ escrito.errorname = nil
+ else
+ print("error '" .. escrito.errorname .. "', quitting")
+ -- os.exit()
+ end
+ end
+
+ return true
+ end
+
+end
+
+do
+
+ -- some of the errors will never actually happen
+
+ local errornames = {
+ "dictfull", "dictstackoverflow", "dictstackunderflow", "execstackoverflow",
+ "interrupt", "invalidaccess", "invalidexit", "invalidfileaccess", "invalidfont", "invalidrestore",
+ "ioerror", "limitcheck", "nocurrentpoint", "rangecheck", "stackoverflow", "stackunderflow",
+ "syntaxerror", "timeout", "typecheck", "undefined", "undefinedfilename", "undefinedresult",
+ "unmatchedmark", "unregistered", "VMerror"
+ }
+
+ local generic_error_proc = [[{
+ $error /newerror true put
+ $error exch /errorname exch put
+ $error exch /command exch put
+ count array astore $error /ostack 3 -1 roll put
+ $error /dstack countdictstack array dictstack put
+ countexecstack array execstack aload pop pop count array astore $error /estack 3 -1 roll put
+ stop
+ } bind ]]
+
+ local generic_handleerror_proc = [[{
+ $error begin
+ /newerror false def
+ (%%[ Error: ) print
+ errorname print
+ (; OffendingCommand: ) print
+ command ==
+ ( ]%%\n) print flush
+ end
+ }]]
+
+ local enabled
+
+ local function interpret(data)
+ if enabled then
+ push_opstack { 'file', 'unlimited', 'executable', add_VM(data), 1, #data, 'r', stdin }
+ push_execstack { 'operator', 'unlimited', 'executable', operators.stopped, 'stopped' }
+ while true do
+ if not do_exec() then
+ local v = pop_opstack()
+ if v and v[4] == true then
+ local proc = {
+ { 'name', 'unlimited', 'executable', add_VM('errordict') }, -- hm, errordict
+ { 'name', 'unlimited', 'literal', add_VM('handleerror') },
+ { 'operator', 'unlimited', 'executable', operators.get, 'get' },
+ { 'operator', 'unlimited', 'executable', operators.exec, 'exec' },
+ }
+ push_execstack { 'array', 'unlimited', 'executable', add_VM(proc), 1, #proc, 'i' }
+ else
+ return
+ end
+ end
+ end
+ end
+ end
+
+ local function close()
+ for i=1,#initializers do
+ initializers[i](true)
+ end
+ enabled = false
+ end
+
+ local function open(options)
+ enabled = true
+ local starttime = os.clock()
+ local stoptime = nil
+ for i=1,#initializers do
+ initializers[i]()
+ end
+ if type(options) == "table" then
+ devicename = options.device or "pdf"
+ findfont = options.findfont or findfont
+ randomseed = options.randomseed or randomseed -- todo
+ calculatebox = options.calculatebox
+ else
+ devicename = "pdf"
+ end
+ device = devices[devicename] or devices.pdf
+ operators.initgraphics()
+ for i=1,#errornames do
+ interpret(formatters["errordict /%s %s put"](errornames[i],generic_error_proc), INITDEBUG)
+ end
+ -- set up the error handler
+ interpret("systemdict /= { 20 string cvs print } bind put", INITDEBUG)
+ interpret("systemdict /prompt { (PS>) print flush } bind put", INITDEBUG)
+ interpret(format("errordict /handleerror %s bind put", generic_handleerror_proc), INITDEBUG)
+ interpret("systemdict /handleerror {errordict /handleerror get exec } bind put", INITDEBUG)
+ -- user dict initializations
+ interpret(format("/quit { stop } bind def"), INITDEBUG)
+ interpret(format("userdict /#copies 1 put"), INITDEBUG)
+ local job = {
+ runtime = 0,
+ interpret = interpret,
+ boundingbox = boundingbox,
+ close = function()
+ close()
+ local runtime = os.clock() - starttime
+ job.runtime = runtime
+ return runtime
+ end,
+ }
+ return job
+ end
+
+ escrito.open = open
+
+ if context then
+
+ function escrito.convert(options)
+ if type(options) == "table" then
+ local data = options.data
+ if not data or data == "" then
+ local buffer = options.buffer
+ local filename = options.filename -- needs escaping
+ if buffer and buffer ~= "" then
+ data = buffers.getcontent(buffer)
+ elseif filename and filename ~= "" then
+ data = io.loaddata(filename) -- use resolver
+ end
+ end
+ if data and data ~= "" then
+ local e = open(options)
+-- print(data)
+ e.interpret(data)
+ return e.close()
+ end
+ end
+ return 0
+ end
+
+ end
+
+ escrito.devices = devices
+
+end
+
+return escrito
diff --git a/tex/context/modules/mkiv/m-escrito.mkiv b/tex/context/modules/mkiv/m-escrito.mkiv
new file mode 100644
index 000000000..763857918
--- /dev/null
+++ b/tex/context/modules/mkiv/m-escrito.mkiv
@@ -0,0 +1,184 @@
+%D \module
+%D [ file=m-escrito,
+%D version=2015.09.27,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=ESCRITO,
+%D author={Taco Hoekwater \& Hans Hagen},
+%D date=\currentdate,
+%D copyright={\CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\registerctxluafile{m-escrito}{1.001}
+
+%D This is a fun project and not meant for production (yet). It's a follow up on a
+%D project by Taco presented at a Bacho\TeX\ meeting years ago. I probably messed up
+%D the code so much that some things don't work but then, fonts are not really
+%D supported well anyway. However for simple \POSTSCRIPT\ things work out ok.
+%D
+%D I (Hans) will occasionally have a look at the code. Who knows what our trips to
+%D \TeX\ meetings lead to.
+
+\unprotect
+
+\unexpanded\def\startESCRITOgraphic#1#2#3#4%
+ {\dontleavehmode
+ \begingroup
+ \MPllx#1\onebasepoint
+ \MPlly#2\onebasepoint
+ \MPurx#3\onebasepoint
+ \MPury#4\onebasepoint
+ \setbox\b_meta_graphic\hbox\bgroup}
+
+\unexpanded\def\stopESCRITOgraphic
+ {\egroup
+ \setbox\b_meta_graphic\ruledhbox\bgroup
+ \kern-\MPllx\raise-\MPlly\box\b_meta_graphic
+ \egroup
+ \wd\b_meta_graphic\dimexpr\MPurx-\MPllx\relax
+ \ht\b_meta_graphic\dimexpr\MPury-\MPlly\relax
+ \dp\b_meta_graphic\zeropoint
+ \box\b_meta_graphic
+ \endgroup}
+
+\unexpanded\def\flushESCRITOtext#1#2#3% no fratures so pretty weak, better use overlays
+ {\smash{\rlap{\definedfont[#1 at #2bp]#3}}}
+
+\unexpanded\def\stopESCRITO
+ {\edef\p_option{\namedbufferparameter{ESCRITO}\c!option}%
+ \ctxlua{escrito.convert {
+ buffer = "\thedefinedbuffer{ESCRITO}",
+ calculatebox = \ifx\p_option\v!fit true\else false\fi,
+ }}}
+
+\unexpanded\def\processESCRITO[#1]%
+ {\begingroup
+ \getdummyparameters[\c!file=,\c!option=,#1]%
+ \edef\p_option{\dummyparameter\c!option}%
+ \ctxlua{escrito.convert {
+ filename = "\dummyparameter\c!file",
+ calculatebox = \ifx\p_option\v!fit true\else false\fi,
+ }}%
+ \endgroup}
+
+\definebuffer
+ [ESCRITO]
+
+\setupbuffer
+ [ESCRITO]
+ [\c!option=,
+ \c!after=\processESCRITO]
+
+\protect
+
+% This will move to m-escrito.lua once we know how to deal with it ... no time
+% now.
+
+\startluacode
+
+ local literal = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral))
+ literal.mode = 0
+
+ local function newliteral(result)
+ local l = nodes.copy(literal)
+ l.data = result
+ return l
+ end
+
+ local p = escrito.devices.pdf
+
+ function p.startpage(llx,lly,urx,ury)
+ context.startESCRITOgraphic(llx,lly,urx,ury)
+ end
+
+ function p.stoppage()
+ context.stopESCRITOgraphic()
+ end
+
+ function p.flushpage(result)
+ context(newliteral(result))
+ end
+
+ -- todo
+
+ local fontnames = { }
+ local fontfiles = { }
+
+ fontnames['NimbusSanL-Regu'] = 'Sans'
+ fontnames['StandardSymL'] = 'rpsyr'
+ fontnames['dejavuserif-regular'] = 'dejavuserif-regular'
+
+ function p.showfont(object)
+ local color = object.color
+ local ctype = object.colortype
+ local matrix = object.matrix
+ local text = object.string
+ local size = object.fontmatrix[1] * 1000
+ local result = { "q" }
+ context(newliteral(formatters['%f %f %f %f %f %f cm'](matrix[1],matrix[2],matrix[3],matrix[4],matrix[5],matrix[6])))
+ if ctype == "rgb" then
+ local r, g, b = color[1], color[2], color[3]
+ context(newliteral(formatters["%f %f %f rg %f %f %f RG"](r,g,b,r,g,b)))
+ elseif ctype == "cmyk" then
+ local c, m, y, k = color[1], color[2], color[3], color[4]
+ context(newliteral(formatters["%f %f %f k %f %f %f K"](c,m,y,k,c,m,y,k)))
+ elseif ctype == "gray" then
+ context(newliteral(formatters["%f g %f G"](color,color)))
+ end
+ context.flushESCRITOtext(fontnames[object.fontname],size,text)
+ context(newliteral("Q"))
+ end
+
+ local function findfont(fontname)
+ return fontfiles[fontname]
+ end
+
+\stopluacode
+
+\continueifinputfile{m-escrito.mkiv}
+
+\starttext
+
+% \startluacode
+% local n = 5
+% for i=1,n do
+% context.startTEXpage()
+% local runtime = escrito.convert { filename = "tiger.eps", calculatebox = true }
+% context.par()
+% context("calculated boundingbox, time: %s",runtime)
+% context.stopTEXpage()
+% end
+% for i=1,n do
+% context.startTEXpage()
+% local runtime = escrito.convert { filename = "tiger.eps", calculatebox = false }
+% context.par()
+% context("built in boundingbox, time: %s",runtime)
+% context.stopTEXpage()
+% end
+% \stopluacode
+
+\startTEXpage
+ \startESCRITO
+ (tiger.eps) run
+ \stopESCRITO
+\stopTEXpage
+
+\startTEXpage
+ \setupbuffer[ESCRITO][option=fit]%
+ \startESCRITO
+ (tiger.eps) run
+ \stopESCRITO
+\stopTEXpage
+
+\startTEXpage
+ \processESCRITO[file=tiger.eps]
+\stopTEXpage
+
+\startTEXpage
+ \processESCRITO[file=tiger.eps,option=fit]
+\stopTEXpage
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/m-fields.mkiv b/tex/context/modules/mkiv/m-fields.mkiv
new file mode 100644
index 000000000..46b77f8d3
--- /dev/null
+++ b/tex/context/modules/mkiv/m-fields.mkiv
@@ -0,0 +1,70 @@
+%D \module
+%D [ file=m-fields,
+%D version=2010.03.14,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Fields,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D A rather old example of field usage is the following. It
+%D makes no sense to have this in the core.
+%D
+%D \starttyping
+%D before \fillinfield[oeps]{whatever} after
+%D \stoptyping
+
+\startJSpreamble{FillInField} used later
+ function CheckFillInField(right) {
+ if (event.value.toLowerCase() == right.toLowerCase()) {
+ event.target.hidden = true ;
+ }
+ event.value = ""
+ }
+\stopJSpreamble
+
+\newcount\noffillinfields
+
+\definefieldcategory
+ [fillinfield]
+ [\c!n=1024,
+ \c!height=\strutht,
+ \c!depth=\strutdp,
+ \c!align=\v!middle,
+ \c!color=red,
+ \c!fieldframecolor=blue,
+ \c!fieldbackgroundcolor=\s!white,
+ \c!validate=JS(CheckFillInField{\therightanswer})]
+
+\def\fillinfield
+ {\dosingleempty\dofillinfield}
+
+\def\dofillinfield[#1]#2%
+ {\dontleavehmode
+ \hbox
+ {\forgetall
+ \global\advance\noffillinfields\plusone
+ \edef\currentfillinfieldname{fillinfield:\number\noffillinfields}%
+ \useJSscripts[ans]%
+ \definefieldbody
+ [\currentfillinfieldname]
+ [\c!type=\v!line,
+ \c!category=fillinfield]%
+ \doifelsenothing{#1}
+ {\def\therightanswer{#2}}
+ {\def\therightanswer{#1}}%
+ \setbox0\hbox{\strut#2}%
+ \setbox2\hbox{\strut\therightanswer}%
+ \dimen0=\dimexpr\ifdim\wd0>\wd2 \wd0 \else \wd2 \fi + .2em\relax
+ \hbox to \wd0
+ {\wd0\zeropoint
+ \box0
+ \hss\fieldbody[\currentfillinfieldname][\c!width=\dimen0]\hss}}}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-format.mkiv b/tex/context/modules/mkiv/m-format.mkiv
new file mode 100644
index 000000000..7cedd803f
--- /dev/null
+++ b/tex/context/modules/mkiv/m-format.mkiv
@@ -0,0 +1,411 @@
+%D \module
+%D [ file=m-formay,
+%D version=ancient,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Ancient Formatting Code,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Here is some code that I had laying around and had forgotten
+%D about. Let's make it a module and see if there is interest in
+%D such things.
+
+% \defineformatblock [poem]
+% \defineformatsegment [verse] % [poem]
+% \defineformatline [line] % [verse]
+%
+% \startpoem [title] [author]
+% \startverse [ref]
+% \startline [ref]
+%
+% block : voor na tussen *tekstletter *tekstkleur
+%
+% segment : voor na tussen *tekstletter *tekstkleur
+% : links rechts linkeroffset rechteroffset
+% : ?marge *evenmarge *onevenmarge breedte
+% : nummer *nummercommando *conversie
+% : nummerletter nummerkleur *label
+%
+% line : voor na tussen *tekstletter *tekstkleur
+% : nummer *nummercommando *conversie
+% : nummerletter nummerkleur *label
+%
+% * = todo
+
+\unprotect
+
+\definesystemvariable {fx} % format block
+\definesystemvariable {fy} % format segment
+\definesystemvariable {fz} % format line
+
+\def\defineformatblock
+ {\dodoubleempty\dodefineformatblock}
+
+\def\dodefineformatblock[#1][#2]%
+ {\setupformatblock
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,#2]%
+ \setvalue{\e!start#1}{\startformatblock[#1]}%
+ \setvalue{\e!stop #1}{\stopformatblock}}
+
+\def\setupformatblock
+ {\dodoubleempty\dosetupformatblock}
+
+\def\setupformatblock[#1]%
+ {\getparameters[\??fx#1]}
+
+\def\startformatblock[#1]%
+ {\dotriplegroupempty\dostartformatblock{#1}}
+
+\def\dostartformatblock#1#2#3
+ {\bgroup
+ \getvalue{\??fx#1\c!before}
+ \doglobal\newcounter\formatsegmentcounter
+ \doglobal\newcounter\formatlinecounter
+ \doglobal\newcounter\formatlinesubcounter
+ \doglobal\newcounter\formatlinemaxcounter
+ \doifsomething{#2}{\leftaligned{#2}\getvalue{\??fx#1\c!inbetween}}
+ \def\stopformatblock%
+ {\doifsomething{#3}{\getvalue{\??fx#1\c!inbetween}\leftaligned{#3}}
+ \getvalue{\??fx#1\c!after}
+ \egroup}}
+
+\def\defineformatsegment
+ {\dodoubleempty\dodefineformatsegment}
+
+\def\dodefineformatsegment[#1][#2]%
+ {\setupformatsegment
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,\c!left=,\c!right=,
+ \c!leftoffset=\!!zeropoint,\c!rightoffset=\!!zeropoint,
+ %\c!margin=\!!zeropoint,\c!evenmargin=\!!zeropoint,\c!oddmargin=\hsize,
+ \c!width=\hsize,\c!numberstyle=,\c!numbercolor=,\c!number=\v!no,
+ \c!numbercommand=,\c!conversion=,\c!label=,
+ #2]%
+ \setvalue{\e!start#1}{\startformatsegment[#1]}%
+ \setvalue{\e!stop #1}{\stopformatsegment}}
+
+\def\setupformatsegment
+ {\dodoubleempty\dosetupformatsegment}
+
+\def\setupformatsegment[#1]%
+ {\getparameters[\??fy#1]}
+
+\def\placeformatsegmentcounter
+ {\formatsegmentcounter\quad\hphantom{\placeformatlinecounter}}
+
+\def\placeformatlinecounter
+ {\formatlinecounter}
+
+\def\startformatsegment[#1]%
+ {\bgroup
+ \doifelsevalue{\??fy#1\c!number}\v!yes
+ {\def\doplaceformatsegmentcounter
+ {\inleftmargin
+ {\doattributes{\??fy#1}\c!numberstyle\c!numbercolor
+ {\placeformatsegmentcounter}}}}
+ {\let\doplaceformatsegmentcounter\relax}%
+ \getvalue{\??fy#1\c!before}
+ \doglobal\increment\formatsegmentcounter
+ \def\formatrightoffset{\getvalue{\??fy#1\c!rightoffset}}
+ \def\formatleftoffset {\getvalue{\??fy#1\c!leftoffset}}
+ \def\formatminwidth {\getvalue{\??fy#1\c!minwidth}}
+ \def\formatwidth {\getvalue{\??fy#1\c!width}}
+ %\def\formatmargin {\getvalue{\??fy#1\c!margin}}
+ \def\formatbefore {\getvalue{\??fy#1\c!before}}
+ \def\formatinbetween {\getvalue{\??fy#1\c!inbetween}}
+ \def\formatafter {\getvalue{\??fy#1\c!after}}
+ \def\formatleft {\getvalue{\??fy#1\c!left}}
+ \def\formatright {\getvalue{\??fy#1\c!right}}
+ \@@segmentvarianta
+ \getvalue{@@segmentvariant\getvalue{\??fy#1\c!alternative}}
+ \def\stopformatsegment
+ {\getvalue{\??fy#1\c!after}
+ \egroup}}
+
+\newif\iftraceformatblock
+
+\def\@@segmentvarianta % ragged right, symbols
+ {\let\formatraggedness\raggedright
+ \let\dostartformatline\dostartformatlineab
+ \let\formatleftfirst\relax \let\formatrightfirst\hfill
+ \let\formatleftnext \hfill \let\formatrightnext \relax}
+
+\def\@@segmentvariantb % ragged right, equal parts, symbols
+ {\let\formatraggedness\raggedcenter
+ \let\dostartformatline\dostartformatlineab
+ \let\formatleftfirst\relax \let\formatrightfirst\hfill
+ \let\formatleftnext \hfill \let\formatrightnext \relax}
+
+\def\@@segmentvariantc % ragged right
+ {\let\formatraggedness\veryraggedright
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\relax \let\formatrightnext\hfill}
+
+\def\@@segmentvariantd % ragged center
+ {\let\formatraggedness\veryraggedcenter
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\hfill \let\formatrightnext\hfill}
+
+\def\@@segmentvariante % ragged left
+ {\let\formatraggedness\veryraggedleft
+ \let\dostartformatline\dostartformatlinecde
+ \let\formatleftnext\hfill \let\formatrightnext\relax}
+
+\def\defineformatline
+ {\dodoubleempty\dodefineformatline}
+
+\def\dodefineformatline[#1][#2]%
+ {\setupformatline
+ [#1]
+ [\c!before=\blank,\c!after=\blank,\c!inbetween=\blank,
+ \c!textstyle=,\c!textcolor=,
+ \c!number=\v!no,\c!numbercommand=,\c!conversion=,
+ \c!numberstyle=,\c!numbercolor=,\c!label=,
+ #2]%
+ \setvalue{\e!start#1}{\startformatline[#1]}%
+ \setvalue{\e!stop #1}{\stopformatline}}
+
+\def\setupformatline
+ {\dodoubleempty\dosetupformatline}
+
+\def\setupformatline[#1]%
+ {\getparameters[\??fz#1]}
+
+\newconditional\formatforcedbreak
+
+\def\startformatline[#1]%
+ {\bgroup
+ \doifelsevalue{\??fz#1\c!number}\v!yes
+ {\def\doplaceformatlinecounter
+ {\inleftmargin
+ {\doattributes{\??fz#1}\c!numberstyle\c!numbercolor
+ {\placeformatlinecounter}}}}
+ {\let\doplaceformatlinecounter\relax}%
+ \global\setfalse\formatforcedbreak
+ \def\\{\break\global\settrue\formatforcedbreak}%
+ \hsize\formatwidth
+ \doglobal\increment\formatlinecounter
+ \par
+ \nobreak
+ \def\stopformatline
+ {\unskip\unskip\unskip\unskip\unskip\egroup
+ \let\doplaceformatsegmentcounter\relax}
+ \postponenotes
+ \dowithnextbox{\dostartformatline}\hbox\bgroup\ignorespaces}
+
+\def\dostartformatlineab
+ {%\dosetleftskipadaption\formatmargin
+ %\advance\hsize-\leftskipadaption\relax
+ \ifdim\nextboxwd>\hsize
+ \beginofshapebox
+ \forgetall
+ \hangafter\plusone
+ \hangindent\formatleftoffset
+ \formatraggedness
+ \hskip\formatrightoffset
+ \unhbox\nextbox\par
+ \endofshapebox
+ %\advance\hsize \leftskipadaption
+ \doglobal\newcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\increment\formatlinesubcounter}
+ \global\let\formatlinemaxcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\decrement\formatlinesubcounter
+ \ifnum\formatlinesubcounter=\zerocount
+ \doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ \hskip-\formatrightoffset
+ %\hskip\leftskipadaption
+ \formatleftfirst
+ \unhbox\shapebox
+ \ifnum\formatlinemaxcounter>\plusone
+ \ifx\formatright\empty\else
+ \shapedhbox to \zeropoint{\formatright\hss}%
+ \fi
+ \fi
+ \formatrightfirst
+ \iftraceformatblock
+ \ruledhskip\formatrightoffset\hskip-\formatrightoffset
+ \fi
+ \else
+ %\hskip\leftskipadaption
+ \iftraceformatblock
+ \ruledhskip\formatleftoffset\hskip-\formatleftoffset
+ \fi
+ \formatleftnext
+ \ifx\formatleft\empty\else
+ \shapedhbox to \zeropoint{\hss\formatleft}%
+ \fi
+ \unhbox\shapebox
+ \formatrightnext
+ \fi}
+ \flushshapebox
+ \else
+ \dontleavehmode\hbox
+ {\doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ %\hskip\leftskipadaption
+ \formatleftfirst
+ \unhbox\nextbox
+ \formatrightfirst}
+ \fi
+ \par
+ \egroup}
+
+\def\dostartformatlinecde
+ {%\dosetleftskipadaption\formatmargin
+ %\advance\hsize -\leftskipadaption\relax
+ \dimen0=\hsize
+ \ifconditional\formatforcedbreak\else
+ \ifdim\formatminwidth>\zeropoint\relax
+ \ifdim\nextboxwd>\hsize
+ \doloop
+ {\global\dimen1=\dimen0
+ \beginofshapebox
+ \hsize\dimen0
+ \forgetall
+ \formatraggedness
+ \unhcopy\nextbox\par
+ \endofshapebox
+ \reshapebox
+ {\setbox\scratchbox=\hbox{\unhbox\shapebox}%
+ \ifdim\wd\scratchbox<\dimen1
+ \global\dimen1=\wd\scratchbox
+ \fi}
+ \ifdim\dimen1<\formatminwidth\relax
+ \advance\dimen0 by -.25em
+ \else
+ \exitloop
+ \fi
+ \ifdim\dimen0<10em
+ \dimen0=\hsize
+ \exitloop
+ \fi}
+ \fi
+ \fi
+ \fi
+ \beginofshapebox
+ \hsize\dimen0
+ \forgetall
+ \formatraggedness
+ \unhcopy\nextbox\par
+ \endofshapebox
+ %\advance\hsize \leftskipadaption
+ \doglobal\newcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\increment\formatlinesubcounter}%
+ \global\let\formatlinemaxcounter\formatlinesubcounter
+ \reshapebox
+ {\doglobal\decrement\formatlinesubcounter
+ \ifnum\formatlinesubcounter=\zerocount
+ \doplaceformatsegmentcounter
+ \doplaceformatlinecounter
+ \fi
+ %\hskip\leftskipadaption
+ \formatleftnext
+ \unhbox\shapebox
+ \formatrightnext\strut}% strut prevents unskip
+ \flushshapebox
+ \par
+ \egroup}
+
+\defineformatblock[poem]
+ [\c!before=\blank,
+ \c!inbetween={\blank[\v!medium]},
+ \c!after=\blank]
+
+\defineformatsegment[verse]
+ [\c!alternative=\v!left,
+ \c!width=\hsize,
+ %\c!margin=\!!zeropoint,
+ \c!before={\blank[\v!medium]},
+ \c!after={\blank[\v!medium]},
+ \c!inbetween={\blank[\v!medium]},
+ \c!leftoffset=3em,
+ \c!rightoffset=2em,
+ \c!minwidth=5em,
+ \c!left={$[$\enspace},
+ \c!right={\enspace$]$}]
+
+\defineformatline[line]
+ []
+
+\protect
+
+\doifnotmode{demo} {\endinput}
+
+% evt defineblank[formatbefore,formatinbetween,formatafter]
+
+%\showframe \traceformatblocktrue
+
+\usemodule[visual]
+
+\setuplayout[height=middle,topspace=1cm,header=0pt,footer=0pt]
+\setupbodyfont[10pt]
+
+% All interfaces supported, but testing with english; todo:
+% more options, more alternatives, inheritance and mixed
+% definitions, and so.
+
+\starttext
+
+\startbuffer
+\startbuffer[poem]
+\startpoem{A Random Poem}{Hans Hagen}
+ \startverse
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \stopverse
+ \startverse
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \startline \fakewords{4}{8} \stopline
+ \stopverse
+\stoppoem
+\stopbuffer
+
+\setupformatsegment[verse][width=.4\hsize,number=yes,numberstyle=slanted]
+\setupformatline [line] [number=yes,numberstyle=smallslanted]
+
+\startbuffer[x]
+\setupformatsegment[verse][leftoffset=0pt,rightoffset=0pt,left=,right=]
+\stopbuffer
+
+\section{Alternative A}
+
+\setupformatsegment[verse][alternative=a] {\getbuffer[poem]}
+\setupformatsegment[verse][alternative=a] {\getbuffer[x,poem]}
+
+\section{Alternative B}
+
+\setupformatsegment[verse][alternative=b] {\getbuffer[poem]}
+\setupformatsegment[verse][alternative=b] {\getbuffer[x,poem]}
+
+\section{Alternative C}
+
+\setupformatsegment[verse][alternative=c] {\getbuffer[poem]}
+
+\section{Alternative D}
+
+\setupformatsegment[verse][alternative=d] {\getbuffer[poem]}
+
+\section{Alternative E}
+
+\setupformatsegment[verse][alternative=e] {\getbuffer[poem]}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-graph.mkiv b/tex/context/modules/mkiv/m-graph.mkiv
new file mode 100644
index 000000000..62c4ec4cb
--- /dev/null
+++ b/tex/context/modules/mkiv/m-graph.mkiv
@@ -0,0 +1,133 @@
+%D \module
+%D [ file=m-graph,
+%D version=2008.09.08,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\METAPOST\ graph module support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% We just assume lua specification instead of the graph ones that
+% are limited by what mp can do. We support @ as replacement for
+% the percent symbol. We also add a specifier when no one is given.
+
+\unprotect
+
+\defineMPinstance
+ [graph]
+ [\s!format=metafun,
+ \s!extensions=\v!yes,
+ \s!initializations=\v!yes,
+ \c!method=\s!double]
+
+\startMPdefinitions{graph}
+ if unknown context_grap : input mp-grap.mpiv ; fi ;
+\stopMPdefinitions
+
+\protect
+
+\continueifinputfile{m-graph.mkiv}
+
+%D We put this test here as in \type {meta-tex.mkiv} it would abort due to redefinition
+%D of namespaces.
+
+\starttext
+
+\startMPpage[instance=graph]
+ label.rt(format("@g","1e-8"), (0, 0)) ;
+ label.rt(format("@g","1e+8"), (2cm, 0)) ;
+ label.rt(format("@g","1e-10"), (0, -0.5cm)) ;
+ label.rt(format("@g","1e+10"), (2cm,-0.5cm)) ;
+ label.rt(format("@g","1e-12"), (0, -1.0cm)) ;
+ label.rt(format("@g","1e+12"), (2cm,-1.0cm)) ;
+ label.rt(format("@g","1e-0"), (0, -1.5cm)) ;
+ label.rt(format("@g","1e+0"), (2cm,-1.5cm)) ;
+ label.rt(format("@g","1"), (0, -2.0cm)) ;
+ label.rt(format("@g","1"), (2cm,-2.0cm)) ;
+ label.rt(format("@g","1e-102"),(0, -2.5cm)) ;
+ label.rt(format("@g","1e+102"),(2cm,-2.5cm)) ;
+ currentpicture := currentpicture shifted (-4cm,0) ;
+ %
+ label.rt(format("@j","1e-8"), (0, 0)) ;
+ label.rt(format("@j","1e+8"), (2cm, 0)) ;
+ label.rt(format("@j","1e-10"), (0, -0.5cm)) ;
+ label.rt(format("@j","1e+10"), (2cm,-0.5cm)) ;
+ label.rt(format("@j","1e-12"), (0, -1.0cm)) ;
+ label.rt(format("@j","1e+12"), (2cm,-1.0cm)) ;
+ label.rt(format("@j","1e-0"), (0, -1.5cm)) ;
+ label.rt(format("@j","1e+0"), (2cm,-1.5cm)) ;
+ label.rt(format("@j","1"), (0, -2.0cm)) ;
+ label.rt(format("@j","1"), (2cm,-2.0cm)) ;
+ label.rt(format("@j","1e-102"),(0, -2.5cm)) ;
+ label.rt(format("@j","1e+102"),(2cm,-2.5cm)) ;
+ label.rt(formatted("(@f,@f)",(1.23,4.56)),(0cm,-3.0cm)) ;
+ label.rt(formatted("(@i,@i)",(1.23,4.56)),(0cm,-3.5cm)) ;
+ label.rt(formatted("(@g,@g)",(1.23,4.56)),(0cm,-4.0cm)) ;
+ label.rt(formatted("(@e,@e)",(1.23,4.56)),(0cm,-4.5cm)) ;
+ label.rt(formatted("(@j,@j)",(1.23,4.56)),(0cm,-5.0cm)) ;
+\stopMPpage
+
+\stoptext
+
+% \startMPpage[instance=graph]
+% draw begingraph(3in,2in);
+% gdraw "t:/metapost/grphdata/agepop91.d";
+% endgraph;
+% \stopMPpage
+
+% \startMPpage[instance=graph]
+% draw begingraph(3in,2in);
+% gdraw "agepop91.d" plot btex $\bullet$ etex;
+% endgraph;
+% \stopMPpage
+
+% \startMPpage[instance=graph]
+% draw begingraph(3in,2in);
+% glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT);
+% glabel.bot(btex Age in years etex, OUT);
+% gdraw "agepopm.d";
+% endgraph;
+% \stopMPpage
+
+% \startMPpage[instance=graph]
+% draw begingraph(3in,2in);
+% glabel.lft(btex \vbox{\hbox{Population} \hbox{in millions}} etex, OUT);
+% glabel.bot(btex Age in years etex, OUT);
+% setrange(origin, whatever,whatever);
+% gdraw "agepopm.d";
+% endgraph;
+% \stopMPpage
+
+% \startMPpage[instance=graph]
+% draw begingraph(2.3in,2in);
+% setcoords(log,log);
+% glabel.lft(btex Seconds etex,OUT);
+% glabel.bot(btex Matrix size etex,
+% OUT);
+% gdraw "matmul.d" dashed evenly;
+% glabel.ulft(btex Standard etex,8);
+% gdraw "matmul.d";
+% glabel.lrt(btex Strassen etex,7);
+% endgraph;
+% \stopMPpage
+
+% \startMPpage[instance=graph]
+% draw begingraph(6.5cm,4.5cm);
+% setrange(80,0, 90,whatever);
+% glabel.bot(btex Year etex, OUT);
+% glabel.lft(btex \vbox{\hbox{Emissions in} \hbox{thousands of}
+% \hbox{metric tons} \hbox{(heavy line)}}etex, OUT);
+% gdraw "lead.d" withpen pencircle scaled 1.5pt;
+% autogrid(,otick.lft);
+% setcoords(linear,linear);
+% setrange(80,0, 90,whatever);
+% glabel.rt(btex \vbox{\hbox{Micrograms} \hbox{per cubic}
+% \hbox{meter of air} \hbox{(thin line)}}etex, OUT);
+% gdraw "lead.d";
+% autogrid(otick.bot,otick.rt);
+% endgraph;
+% \stopMPpage
diff --git a/tex/context/modules/mkiv/m-hemistich.mkiv b/tex/context/modules/mkiv/m-hemistich.mkiv
new file mode 100644
index 000000000..7a849d415
--- /dev/null
+++ b/tex/context/modules/mkiv/m-hemistich.mkiv
@@ -0,0 +1,120 @@
+%D \module
+%D [ file=m-hemistich,
+%D version=2013.08.26,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Hemistiches,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is an experimental module for Idris. More is possible but not now.
+
+\unprotect
+
+\installcorenamespace{hemistich}
+
+\installcommandhandler \??hemistich {hemistich} \??hemistich
+
+\setuphemistich
+ [\c!width=\v!local,
+ \c!distance=4\emwidth,
+ \c!separator=\vl\hskip.25em\vl]
+
+\unexpanded\def\hemistiches
+ {\dosingleempty\dohemistiches}
+
+\unexpanded\def\dohemistiches
+ {\dodohemistiches\empty}
+
+\unexpanded\def\dodohemistiches#1[#2]#3#4%
+ {\dontleavehmode
+ \begingroup
+ \doifelseassignment{#2}
+ {\edef\currenthemistich{#1}%
+ \setupcurrenthemistich[#2]}
+ {\def\currenthemistich{#2}}%
+ \doifelse{\hemistichparameter\c!width}\v!local
+ {\scratchwidth\availablehsize}
+ {\scratchwidth\hemistichparameter\c!width\relax}%
+ \spaceskip\zeropoint\s!plus\plusone\s!fill\relax
+ \dostarttagged\t!division\currenthemistich
+ \hbox to \scratchwidth\bgroup
+ \scratchwidth.5\dimexpr\scratchwidth-\hemistichparameter\c!distance\relax
+ \hbox to \scratchwidth\bgroup
+ \dostarttagged\t!construct\c!lefttext
+ \usehemistichstyleandcolor\c!leftstyle\c!leftcolor#3%
+ \dostoptagged
+ \egroup
+ \hss
+ \begingroup
+ \dostarttagged\t!construct\c!separator
+ \usehemistichstyleandcolor\c!separatorstyle\c!separatorcolor
+ \hemistichparameter\c!separator
+ \dostoptagged
+ \endgroup
+ \hss
+ \hbox to \scratchwidth\bgroup
+ \dostarttagged\t!construct\c!righttext
+ \usehemistichstyleandcolor\c!rightstyle\c!rightcolor#4%
+ \dostoptagged
+ \egroup
+ \egroup
+ \dostoptagged
+ \endgroup}
+
+\unexpanded\def\hemistichescaesura#1#2#3%
+ {\dodohemistiches\empty[\c!separator={#2}]{#1}{#3}}
+
+\appendtoks
+ \setvalue{\currenthemistich}{\dohemistiches{\currenthemistich}}%
+\to \everydefinehemistich
+
+\protect
+
+\continueifinputfile{m-hemistich.mkiv}
+
+\setuphemistich
+ [leftcolor=darkred,
+ separatorcolor=darkgreen,
+ rightcolor=darkblue]
+
+\setupwhitespace
+ [big]
+
+\starttext
+
+% \righttoleft
+
+\hemistichescaesura{left side of the brain}{equals}{right side of the brain}
+
+\hemistiches{left side of the brain}{right side of the brain}
+
+\startitemize
+ \startitem
+ \hemistiches{left side of the brain}{right side of the brain}
+ \startitemize
+ \startitem
+ \hemistiches{left side of the brain}{right side of the brain}
+ \startitemize
+ \startitem
+ \hemistiches{left side of the brain}{right side of the brain}
+ \stopitem
+ \stopitemize
+ \stopitem
+ \stopitemize
+ \startitem
+ \hemistiches{left side of the brain}{right side of the brain}
+ \stopitem
+ \stopitem
+\stopitemize
+
+\startitemize
+\item \hemistiches{left side of the brain}{right side of the brain}
+\stopitemize
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/m-ipsum.mkiv b/tex/context/modules/mkiv/m-ipsum.mkiv
new file mode 100644
index 000000000..1c5901d86
--- /dev/null
+++ b/tex/context/modules/mkiv/m-ipsum.mkiv
@@ -0,0 +1,198 @@
+%D \module
+%D [ file=m-ipsum,
+%D version=2012.07.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Ipsum,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D After some discussing on the mailing list I made this example of
+%D an implementation. Of course there can be alternatives as it's a
+%D nice exercise in module writing.
+
+\startluacode
+
+local patterns = lpeg.patterns
+
+local variables = interfaces.variables
+local v_random = variables.random
+
+local lowercase = characters.lower
+
+local ipsum = { }
+moduledata.ipsum = ipsum
+
+local data = { }
+
+local function getfiledata(settings)
+ local filename = settings.filename or ""
+ local filedata = data[filename]
+ if not filedata then
+ local text = resolvers.loadtexfile(filename) or ""
+ local paragraphs = lpeg.match(patterns.paragraphs,text) or { }
+ local sentences = lpeg.match(patterns.sentences, text) or { }
+ local words = lpeg.match(patterns.words, text) or { }
+ for i=1,#words do
+ words[i] = lowercase(words[i])
+ end
+ filedata = {
+ -- [variables.paragraphs] = paragraphs,
+ [variables.paragraph] = paragraphs,
+ [variables.lines] = sentences,
+ [variables.line] = sentences,
+ [variables.words] = words,
+ [variables.word] = words,
+ }
+ -- inspect(filedata)
+ data[filename] = filedata
+ end
+ local d = filedata[settings.alternative or v_paragraph] or filedata[v_paragraph] or { }
+ local nd = #d
+ local n = settings.n
+ if n ~= v_random then
+ n = tonumber(n) or 0
+ if n == 0 then
+ n = nd
+ end
+ end
+ return d, n, nd
+end
+
+function moduledata.ipsum.typeset(settings)
+ local d, n, nd = getfiledata(settings)
+ if nd > 0 then
+ context(settings.before)
+ if n == v_random then
+ context(settings.left)
+ context(d[math.random(1,nd)])
+ context(settings.right)
+ else
+ for i=1,n do
+ context(settings.left)
+ context(d[i])
+ context(settings.right)
+ if i < n then
+ context(settings.inbetween)
+ end
+ end
+ end
+ context(settings.after)
+ end
+end
+
+function moduledata.ipsum.direct(settings)
+ local d, n, nd = getfiledata(settings)
+ if nd == 0 then
+ -- nothing
+ elseif n == v_random then
+ context(d[math.random(1,nd)])
+ else
+ for i=1,n do
+ context(d[i])
+ if i < n then
+ context(settings.separator)
+ end
+ end
+ end
+end
+
+\stopluacode
+
+\unprotect
+
+\installnamespace {ipsum}
+
+\installcommandhandler \????ipsum {ipsum} \????ipsum
+
+\setupipsum
+ [\c!file=lorem,
+ \c!alternative=\v!paragraph,
+ %\c!language=,
+ %\c!styl=,
+ %\c!color=,
+ \c!n=0,
+ \c!left=,
+ \c!right=,
+ \c!before=,
+ \c!after=,
+ \c!separator=,
+ \c!inbetween=]
+
+\installactionhandler{ipsum} % grouped
+
+\startsetups[handler:action:ipsum]
+ \useipsumstyleandcolor\c!style\c!color
+ \uselanguageparameter\ipsumparameter
+ \ctxlua{moduledata.ipsum.typeset {
+ alternative = "\ipsumparameter\c!alternative",
+ filename = "\ipsumparameter\c!file",
+ n = "\ipsumparameter\c!n",
+ left = "\luaescapestring{\ipsumparameter\c!left}",
+ right = "\luaescapestring{\ipsumparameter\c!right}",
+ before = "\luaescapestring{\ipsumparameter\c!before}",
+ after = "\luaescapestring{\ipsumparameter\c!after}",
+ inbetween = "\luaescapestring{\ipsumparameter\c!inbetween}",
+ }}
+\stopsetups
+
+\def\directipsum#1% only one argument, expanded
+ {\ctxlua{moduledata.ipsum.typeset {
+ alternative = "\namedipsumparameter{#1}\c!alternative",
+ filename = "\namedipsumparameter{#1}\c!file",
+ n = "\namedipsumparameter{#1}\c!n",
+ separator = "\luaescapestring{\ipsumparameter\c!separator}",
+ }}
+}
+
+\protect
+
+\continueifinputfile{m-ipsum.mkiv}
+
+\setupbodyfont[dejavu,11pt]
+
+\starttext
+
+ \ipsum[alternative=paragraph,before=\blank,after=\blank,language=la]
+
+ \ipsum[alternative=lines,n=2,right=\par,before=\blank,after=\blank,language=la]
+
+ \ipsum[alternative=lines,n=random,before=\blank,after=\blank,language=la]
+
+ \ipsum[alternative=lines,before=\startitemize,after=\stopitemize,left=\startitem,right=\stopitem,language=la]
+
+ \ipsum[alternative=words,left=(,right=),inbetween=\space,language=la]
+
+ \page
+
+ \defineipsum
+ [ward]
+ [file=ward,
+ before=\blank,
+ after=\blank]
+
+ \defineipsum
+ [ward:itemize]
+ [ward]
+ [alternative=lines,
+ before={\startitemize[packed]},
+ after=\stopitemize,
+ left=\startitem,
+ right=\stopitem]
+
+ \defineipsum
+ [ward:title]
+ [ward]
+ [alternative=lines,
+ n=random]
+
+ \subject{\directipsum{ward:title}}
+
+ \ipsum[ward]
+ \ipsum[ward:itemize]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-json.mkiv b/tex/context/modules/mkiv/m-json.mkiv
new file mode 100644
index 000000000..329aa0f31
--- /dev/null
+++ b/tex/context/modules/mkiv/m-json.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=m-json,
+%D version=2012.08.03,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Json,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is a side effect of looking into json. Currently there are
+%D only a few helpers:
+%D
+%D \starttyping
+%D moduledata.json.tolua (str)
+%D moduledata.json.tostring(val)
+%D \stoptyping
+%D
+%D Nothing spectacular but maybe handy to have around.
+
+\startmodule [json]
+
+% check for: utilities.json
+
+\registerctxluafile{util-jsn}{}
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/m-layout.mkiv b/tex/context/modules/mkiv/m-layout.mkiv
new file mode 100644
index 000000000..5ccf0e987
--- /dev/null
+++ b/tex/context/modules/mkiv/m-layout.mkiv
@@ -0,0 +1,102 @@
+%D \module
+%D [ file=m-layout,
+%D version=2004.01.16,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Additional Layouts,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% layout-preset - thf th tf
+
+%D This is a preliminary module, don't depend on these dimensions yet.
+
+\readsysfile{lang-frq}\donothing\donothing
+\readsysfile{lang-frd}\donothing\donothing
+
+\unprotect
+
+% \def\layouthwratio{\withoutpt\the\dimexpr8\paperheight/\dimexpr(\paperwidth/ 8192)\relax}
+% \def\layouthwratio{\withoutpt\the\dimexpr4\paperheight/\dimexpr(\paperwidth/16384)\relax}
+% \def\layouthwratio{\withoutpt\the\dimexpr2\paperheight/\dimexpr(\paperwidth/32768)\relax}
+
+\def\layouthwratio
+ {\withoutpt\the\dimexpr2\paperheight/(\paperwidth/32768)\relax}
+
+\def\layouthfheight
+ {\dimexpr\layoutparameter\c!header+\layoutparameter\c!headerdistance+
+ \layoutparameter\c!footer+\layoutparameter\c!footerdistance\relax}
+
+\startsetups[preset-1]
+
+ \xdef\layoutwidth {\dimexpr\layoutparameter\c!width\relax}
+ \gdef\layoutheight{\dimexpr\layouthwratio\dimexpr\layoutwidth\relax+\layouthfheight\relax}
+
+\stopsetups
+
+\definelayout
+ [preset-1-1]
+ [\c!preset=preset-1,
+ \c!backspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax,
+ \c!width=\dimexpr2\paperwidth/3\relax,
+ \c!cutspace=\dimexpr(\paperwidth-\layoutwidth)/2\relax,
+ \c!margin=\dimexpr(\paperwidth-\layoutwidth)/3\relax,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance, % \lineheight,
+ \c!footer=\layoutparameter\c!header, % 2\lineheight,
+ \c!topspace=\dimexpr1\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax,
+ \c!bottomspace=\dimexpr2\dimexpr\paperheight-(\layoutheight+\layouthfheight)\relax/3\relax]
+
+\startsetups[preset-2]
+
+ \gdef\layouthstep{\dimexpr\paperwidth /\layoutparameter\c!columns\relax}
+ \gdef\layoutvstep{\dimexpr\paperheight/\layoutparameter\c!columns\relax}
+
+\stopsetups
+
+\definelayout
+ [preset-2-1]
+ [\c!preset=preset-2,
+ \c!columns=12,
+ \c!backspace=\layouthstep,
+ \c!width=\v!middle,
+ \c!cutspace=2\layouthstep,
+ \c!margin=\layouthstep,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance,
+ \c!footer=\layoutparameter\c!header,
+ \c!topspace=\dimexpr\layoutvstep-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax,
+ \c!bottomspace=\dimexpr(2\layoutvstep)-\layoutparameter\c!header-\layoutparameter\c!headerdistance\relax]
+
+\definelayout
+ [preset-2-2]
+ [\c!preset=preset-2,
+ \c!columns=12,
+ \c!backspace=\layouthstep,
+ \c!width=\v!middle,
+ \c!cutspace=2\layouthstep,
+ \c!margin=\layouthstep,
+ \c!header=2\lineheight,
+ \c!headerdistance=\lineheight,
+ \c!height=\v!middle, % \layoutheight
+ \c!footerdistance=\layoutparameter\c!headerdistance,
+ \c!footer=\layoutparameter\c!header,
+ \c!topspace=\layoutvstep,
+ \c!bottomspace=\layoutvstep] % maybe 1.5
+
+% \setuplayout[preset-1-1] test \showframe \page
+% \setuplayout[preset-1-1][width=65\averagecharwidth] \setuplayout[preset-1-1] test \showframe \page
+% \setuplayout[preset-2-1] test \showframe \page
+% \setuplayout[preset-2-1][columns=10] \setuplayout[preset-2-1] test \showframe \page
+% \setuplayout[preset-2-2] test \showframe \page
+% \setuplayout[preset-2-2][columns=10] \setuplayout[preset-2-2] test \showframe \page
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-logcategories.mkiv b/tex/context/modules/mkiv/m-logcategories.mkiv
new file mode 100644
index 000000000..954cd58c4
--- /dev/null
+++ b/tex/context/modules/mkiv/m-logcategories.mkiv
@@ -0,0 +1,3 @@
+\starttext
+ \showlogcategories
+\stoptext
diff --git a/tex/context/modules/mkiv/m-markdown.lua b/tex/context/modules/mkiv/m-markdown.lua
new file mode 100644
index 000000000..1f9402f60
--- /dev/null
+++ b/tex/context/modules/mkiv/m-markdown.lua
@@ -0,0 +1,824 @@
+if not modules then modules = { } end modules ['m-markdown'] = {
+ version = 1.002,
+ comment = "companion to m-markdown.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "see below",
+ license = "see context related readme files"
+}
+
+--[[
+Copyright (C) 2009 John MacFarlane / Khaled Hosny / Hans Hagen
+
+The main parser is derived from the lunamark parser written by John MacFarlane. You
+can download lunamark from:
+
+ http://github.com/jgm/lunamark.git
+
+Khaled Hosny provided the context writer for lunamark and that was used as starting
+point for the mapping. The original code can be fetched from the above location.
+
+While playing with the original code I got the feeling that lpeg could perform better.
+The slowdown was due to the fact that the parser's lpeg was reconstructed each time a
+nested parse was needed. After changing that code a bit I could bring down parsing of
+some test code from 2 seconds to less than 0.1 second so I decided to stick to this
+parser instead of writing my own. After all, the peg code looks pretty impressive and
+visiting Johns pandoc pages is worth the effort:
+
+ http://johnmacfarlane.net/pandoc/
+
+The code here is mostly meant for processing snippets embedded in a context
+documents and is no replacement for pandoc at all. Therefore an alternative is to use
+pandoc in combination with Aditya's filter module.
+
+As I changed (and optimized) the original code, it will be clear that all errors
+are mine. Eventually I might also adapt the parser code a bit more. When I ran into of
+closure stack limitations I decided to flatten the code. The following implementation
+seems to be a couple of hundred times faster than what I started with which is not that
+bad.
+
+This is a second rewrite. The mentioned speed gain largely depended on the kind of
+content: blocks, references and items can be rather demanding. Also, There were
+some limitations with respect to the captures. So, table storage has been removed in
+favor of strings, and nesting has been simplified. The first example at the end of this
+file now takes .33 seconds for 567KB code (resulting in over 1MB) so we're getting there.
+
+There will be a third rewrite eventually.
+]]--
+
+-- todo: we have better quote and tag scanners in ctx
+-- todo: provide an xhtml mapping
+-- todo: add a couple of extensions
+-- todo: check patches to the real peg
+
+local type, next, tonumber = type, next, tonumber
+local lower, upper, gsub, rep, gmatch, format, length = string.lower, string.upper, string.gsub, string.rep, string.gmatch, string.format, string.len
+local concat = table.concat
+local P, R, S, V, C, Ct, Cg, Cb, Cmt, Cc, Cf, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cg, lpeg.Cb, lpeg.Cmt, lpeg.Cc, lpeg.Cf, lpeg.Cs
+local lpegmatch = lpeg.match
+local utfbyte, utfchar = utf.byte, utf.char
+
+moduledata = moduledata or { }
+moduledata.markdown = moduledata.markdown or { }
+local markdown = moduledata.markdown
+
+local nofruns, nofbytes, nofhtmlblobs = 0, 0, 0
+
+---------------------------------------------------------------------------------------------
+
+local nestedparser
+local syntax
+
+nestedparser = function(str) return lpegmatch(syntax,str) end
+
+---------------------------------------------------------------------------------------------
+
+local asterisk = P("*")
+local dash = P("-")
+local plus = P("+")
+local underscore = P("_")
+local period = P(".")
+local hash = P("#")
+local ampersand = P("&")
+local backtick = P("`")
+local less = P("<")
+local more = P(">")
+local space = P(" ")
+local squote = P("'")
+local dquote = P('"')
+local lparent = P("(")
+local rparent = P(")")
+local lbracket = P("[")
+local rbracket = P("]")
+local slash = P("/")
+local equal = P("=")
+local colon = P(":")
+local semicolon = P(";")
+local exclamation = P("!")
+
+local digit = R("09")
+local hexdigit = R("09","af","AF")
+local alphanumeric = R("AZ","az","09")
+
+local doubleasterisks = P("**")
+local doubleunderscores = P("__")
+local fourspaces = P(" ")
+
+local any = P(1)
+local always = P("")
+
+local tab = P("\t")
+local spacechar = S("\t ")
+local spacing = S(" \n\r\t")
+local newline = P("\r")^-1 * P("\n")
+local spaceornewline = spacechar + newline
+local nonspacechar = any - spaceornewline
+local optionalspace = spacechar^0
+local spaces = spacechar^1
+local eof = - any
+local nonindentspace = space^-3
+local blankline = optionalspace * C(newline)
+local blanklines = blankline^0
+local skipblanklines = (optionalspace * newline)^0
+local linechar = P(1 - newline)
+local indent = fourspaces + (nonindentspace * tab) / ""
+local indentedline = indent /"" * C(linechar^1 * (newline + eof))
+local optionallyindentedline = indent^-1 /"" * C(linechar^1 * (newline + eof))
+local spnl = optionalspace * (newline * optionalspace)^-1
+local specialchar = S("*_`*&[]<!\\")
+local normalchar = any - (specialchar + spaceornewline)
+local line = C((any - newline)^0 * newline)
+ + C(any^1 * eof)
+local nonemptyline = (any - newline)^1 * newline
+
+---------------------------------------------------------------------------------------------
+
+local function lineof(c)
+ return (nonindentspace * (P(c) * optionalspace)^3 * newline * blankline^1)
+end
+
+local lineof_asterisks = lineof(asterisk)
+local lineof_dashes = lineof(dash)
+local lineof_underscores = lineof(underscore)
+
+local bullet = nonindentspace * (plus + (asterisk - lineof_asterisks) + (dash - lineof_dashes)) * spaces
+local enumerator = nonindentspace * digit^1 * period * spaces
+
+---------------------------------------------------------------------------------------------
+
+local openticks = Cg(backtick^1, "ticks")
+local closeticks = space^-1 * Cmt(C(backtick^1) * Cb("ticks"), function(s,i,a,b) return #a == #b and i end)
+local intickschar = (any - S(" \n\r`"))
+ + (newline * -blankline)
+ + (space - closeticks)
+ + (backtick^1 - closeticks)
+local inticks = openticks * space^-1 * C(intickschar^1) * closeticks
+
+---------------------------------------------------------------------------------------------
+
+local leader = space^-3
+local nestedbrackets = P { lbracket * ((1 - lbracket - rbracket) + V(1))^0 * rbracket }
+local tag = lbracket * C((nestedbrackets + 1 - rbracket)^0) * rbracket
+local url = less * C((1-more)^0) * more
+ + C((1-spacing- rparent)^1) -- sneaky: ) for resolver
+local title_s = squote * lpeg.C((1-squote )^0) * squote
+local title_d = dquote * lpeg.C((1-dquote )^0) * dquote
+local title_p = lparent * lpeg.C((1-rparent)^0) * rparent
+local title = title_s + title_d + title_p
+local optionaltitle = ((spacing^0 * title * spacechar^0) + lpeg.Cc(""))
+
+local references = { }
+
+local function register_link(tag,url,title)
+ tag = lower(gsub(tag, "[ \n\r\t]+", " "))
+ references[tag] = { url, title }
+end
+
+local function direct_link(label,url,title) -- title is typical html thing
+ return label, url, title
+end
+
+local function indirect_link(label,tag)
+ if tag == "" then
+ tag = label
+ end
+ tag = lower(gsub(tag, "[ \n\r\t]+", " "))
+ local r = references[tag]
+ if r then
+ return label, r[1], r[2]
+ else
+ return label, tag, ""
+ end
+end
+
+local define_reference_parser = (leader * tag * colon * spacechar^0 * url * optionaltitle) / register_link
+local direct_link_parser = tag * spacechar^0 * lparent * (url + Cc("")) * optionaltitle * rparent / direct_link
+local indirect_link_parser = tag * spacechar^0 * tag / indirect_link
+
+local rparser = (define_reference_parser+1)^0
+
+local function referenceparser(str)
+ references = { }
+ lpegmatch(rparser,str)
+end
+
+-- local reftest = [[
+-- [1]: <http://example.com/>
+-- [3]:http://example.com/ (Optional Title Here)
+-- [2]: http://example.com/ 'Optional Title Here'
+-- [a]: http://example.com/ "Optional *oeps* Title Here"
+-- ]]
+--
+-- local linktest = [[
+-- [This link] (http://example.net/)
+-- [an example] (http://example.com/ "Title")
+-- [an example][1]
+-- [an example] [2]
+-- ]]
+--
+-- lpeg.match((define_reference_parser+1)^0,reftest)
+--
+-- inspect(references)
+--
+-- lpeg.match((direct_link_parser/print + indirect_link_parser/print + 1)^0,linktest)
+
+---------------------------------------------------------------------------------------------
+
+local blocktags = table.tohash {
+ "address", "blockquote" , "center", "dir", "div", "p", "pre",
+ "li", "ol", "ul", "dl", "dd",
+ "form", "fieldset", "isindex", "menu", "noframes", "frameset",
+ "h1", "h2", "h3", "h4", "h5", "h6",
+ "hr", "ht", "script", "noscript",
+ "table", "tbody", "tfoot", "thead", "th", "td", "tr",
+}
+
+----- htmlattributevalue = squote * C((any - (blankline + squote))^0) * squote
+----- + dquote * C((any - (blankline + dquote))^0) * dquote
+----- + (any - S("\t >"))^1 -- any - tab - space - more
+----- htmlattribute = (alphanumeric + S("_-"))^1 * spnl * (equal * spnl * htmlattributevalue)^-1 * spnl
+----- htmlcomment = P("<!--") * (any - P("-->"))^0 * P("-->")
+
+----- htmltag = less * spnl * slash^-1 * alphanumeric^1 * spnl * htmlattribute^0 * slash^-1 * spnl * more
+-----
+----- blocktag = Cmt(C(alphanumeric^1), function(s,i,a) return blocktags[lower(a)] and i, a end)
+-----
+----- openblocktag = less * Cg(blocktag, "opentag") * spnl * htmlattribute^0 * more
+----- closeblocktag = less * slash * Cmt(C(alphanumeric^1) * Cb("opentag"), function(s,i,a,b) return lower(a) == lower(b) and i end) * spnl * more
+----- selfclosingblocktag = less * blocktag * spnl * htmlattribute^0 * slash * more
+-----
+----- displayhtml = Cs { "HtmlBlock",
+----- InBlockTags = openblocktag * (V("HtmlBlock") + (any - closeblocktag))^0 * closeblocktag,
+----- HtmlBlock = C(V("InBlockTags") + selfclosingblocktag + htmlcomment),
+----- }
+-----
+----- inlinehtml = Cs(htmlcomment + htmltag)
+
+-- There is no reason to support crappy html, so we expect proper attributes.
+
+local htmlattributevalue = squote * C((any - (blankline + squote))^0) * squote
+ + dquote * C((any - (blankline + dquote))^0) * dquote
+local htmlattribute = (alphanumeric + S("_-"))^1 * spnl * equal * spnl * htmlattributevalue * spnl
+
+local htmlcomment = P("<!--") * (any - P("-->"))^0 * P("-->")
+local htmlinstruction = P("<?") * (any - P("?>" ))^0 * P("?>" )
+
+-- We don't care too much about matching elements and there is no reason why display elements could not
+-- have inline elements so the above should be patched then. Well, markdown mixed with html is not meant
+-- for anything else than webpages anyway.
+
+local blocktag = Cmt(C(alphanumeric^1), function(s,i,a) return blocktags[lower(a)] and i, a end)
+
+local openelement = less * alphanumeric^1 * spnl * htmlattribute^0 * more
+local closeelement = less * slash * alphanumeric^1 * spnl * more
+local emptyelement = less * alphanumeric^1 * spnl * htmlattribute^0 * slash * more
+
+local displaytext = (any - less)^1
+local inlinetext = displaytext / nestedparser
+
+local displayhtml = #(less * blocktag * spnl * htmlattribute^0 * more)
+ * Cs { "HtmlBlock",
+ InBlockTags = openelement * (V("HtmlBlock") + displaytext)^0 * closeelement,
+ HtmlBlock = (V("InBlockTags") + emptyelement + htmlcomment + htmlinstruction),
+ }
+
+local inlinehtml = Cs { "HtmlBlock",
+ InBlockTags = openelement * (V("HtmlBlock") + inlinetext)^0 * closeelement,
+ HtmlBlock = (V("InBlockTags") + emptyelement + htmlcomment + htmlinstruction),
+ }
+
+---------------------------------------------------------------------------------------------
+
+local hexentity = ampersand * hash * S("Xx") * C(hexdigit ^1) * semicolon
+local decentity = ampersand * hash * C(digit ^1) * semicolon
+local tagentity = ampersand * C(alphanumeric^1) * semicolon
+
+---------------------------------------------------------------------------------------------
+
+-- --[[
+
+local escaped = {
+ ["{" ] = "",
+ ["}" ] = "",
+ ["$" ] = "",
+ ["&" ] = "",
+ ["#" ] = "",
+ ["~" ] = "",
+ ["|" ] = "",
+ ["%%"] = "",
+ ["\\"] = "",
+}
+
+for k, v in next, escaped do
+ escaped[k] = "\\char" .. utfbyte(k) .. "{}"
+end
+
+local function c_string(s) -- has to be done more often
+ return (gsub(s,".",escaped))
+end
+
+local c_linebreak = "\\crlf\n" -- is this ok?
+local c_space = " "
+
+local function c_paragraph(c)
+ return c .. "\n\n" -- { "\\startparagraph ", c, " \\stopparagraph\n" }
+end
+
+local function listitem(c)
+ return format("\n\\startitem\n%s\n\\stopitem\n",nestedparser(c))
+end
+
+local function c_tightbulletlist(c)
+ return format("\n\\startmarkdownitemize[packed]\n%s\\stopmarkdownitemize\n",c)
+end
+
+local function c_loosebulletlist(c)
+ return format("\n\\startmarkdownitemize\n\\stopmarkdownitemize\n",c)
+end
+
+local function c_tightorderedlist(c)
+ return format("\n\\startmarkdownitemize[n,packed]\n%s\\stopmarkdownitemize\n",c)
+end
+
+local function c_looseorderedlist(c)
+ return format("\n\\startmarkdownitemize[n]\n%s\\stopmarkdownitemize\n",c)
+end
+
+local function c_inline_html(content)
+ nofhtmlblobs = nofhtmlblobs + 1
+ return format("\\markdowninlinehtml{%s}",content)
+end
+
+local function c_display_html(content)
+ nofhtmlblobs = nofhtmlblobs + 1
+ return format("\\startmarkdowndisplayhtml\n%s\n\\stopmarkdowndisplayhtml",content)
+end
+
+local function c_emphasis(c)
+ return format("\\markdownemphasis{%s}",c)
+end
+
+local function c_strong(c)
+ return format("\\markdownstrong{%s}",c)
+end
+
+local function c_blockquote(c)
+ return format("\\startmarkdownblockquote\n%s\\stopmarkdownblockquote\n",nestedparser(c))
+end
+
+local function c_verbatim(c)
+ return format("\\startmarkdowntyping\n%s\\stopmarkdowntyping\n",c)
+end
+
+local function c_code(c)
+ return format("\\markdowntype{%s}",c)
+end
+
+local levels = { "", "", "", "", "", "" }
+
+local function c_start_document()
+ levels = { "", "", "", "", "", "" }
+ return ""
+end
+
+local function c_stop_document()
+ return concat(levels,"\n") or ""
+end
+
+local function c_heading(level,c)
+ if level > #levels then
+ level = #levels
+ end
+ local finish = concat(levels,"\n",level) or ""
+ for i=level+1,#levels do
+ levels[i] = ""
+ end
+ levels[level] = "\\stopstructurelevel"
+ return format("%s\\startstructurelevel[markdown][title={%s}]\n",finish,c)
+end
+
+local function c_hrule()
+ return "\\markdownrule\n"
+end
+
+local function c_link(lab,src,tit)
+ return format("\\goto{%s}[url(%s)]",nestedparser(lab),src)
+end
+
+local function c_image(lab,src,tit)
+ return format("\\externalfigure[%s]",src)
+end
+
+local function c_email_link(address)
+ return format("\\goto{%s}[url(mailto:%s)]",c_string(address),address)
+end
+
+local function c_url_link(url)
+ return format("\\goto{%s}[url(%s)]",c_string(url),url)
+end
+
+local function f_heading(c,n)
+ return c_heading(n,c)
+end
+
+local function c_hex_entity(s)
+ return utfchar(tonumber(s,16))
+end
+
+local function c_dec_entity(s)
+ return utfchar(tonumber(s))
+end
+
+local function c_tag_entity(s)
+ return s -- we can use the default resolver
+end
+
+--]]
+
+---------------------------------------------------------------------------------------------
+
+--[[
+
+local escaped = {
+ ["<"] = "&lt;",
+ [">"] = "&gt;",
+ ["&"] = "&amp;",
+ ['"'] = "&quot;",
+}
+
+local function c_string(s) -- has to be done more often
+ return (gsub(s,".",escaped))
+end
+
+local c_linebreak = "<br/>"
+local c_space = " "
+
+local function c_paragraph(c)
+ return format("<p>%s</p>\n", c)
+end
+
+local function listitem(c)
+ return format("<li>%s</li>",nestedparser(c))
+end
+
+local function c_tightbulletlist(c)
+ return format("<ul>\n%s\n</ul>\n",c)
+end
+
+local function c_loosebulletlist(c)
+ return format("<ul>\n%s\n</ul>\n",c)
+end
+
+local function c_tightorderedlist(c)
+ return format("<ol>\n%s\n</ol>\n",c)
+end
+
+local function c_looseorderedlist(c)
+ return format("<ol>\n%s\n</ol>\n",c)
+end
+
+local function c_inline_html(content)
+ nofhtmlblobs = nofhtmlblobs + 1
+ return content
+end
+
+local function c_display_html(content)
+ nofhtmlblobs = nofhtmlblobs + 1
+ return format("\n%s\n",content)
+end
+
+local function c_emphasis(c)
+ return format("<em>%s</em>",c)
+end
+
+local function c_strong(c)
+ return format("<strong>%s</strong>",c)
+end
+
+local function c_blockquote(c)
+ return format("<blockquote>\n%s\n</blockquote>",nestedparser(c))
+end
+
+local function c_verbatim(c)
+ return format("<pre><code>%s</code></pre>",c)
+end
+
+local function c_code(c)
+ return format("<code>%s</code>",c)
+end
+
+local c_start_document = ""
+local c_stop_document = ""
+
+local function c_heading(level,c)
+ return format("<h%d>%s</h%d>\n",level,c,level)
+end
+
+local function c_hrule()
+ return "<hr/>\n"
+end
+
+local function c_link(lab,src,tit)
+ local titattr = #tit > 0 and format(" title=%q",tit) or ""
+ return format("<a href=%q%s>%s</a>",src,titattr,nestedparser(lab))
+end
+
+local function c_image(lab,src,tit)
+ return format("<img href=%q title=%q>%s</a>",src,tit,nestedparser(lab))
+end
+
+local function c_email_link(address)
+ return format("<a href=%q>%s</a>","mailto:",address,c_escape(address))
+end
+
+local function c_url_link(url)
+ return format("<a href=%q>%s</a>",url,c_string(url))
+end
+
+local function f_heading(c,n)
+ return c_heading(n,c)
+end
+
+local function c_hex_entity(s)
+ return utfchar(tonumber(s,16))
+end
+
+local function c_dec_entity(s)
+ return utfchar(tonumber(s))
+end
+
+local function c_tag_entity(s)
+ return format("&%s;",s)
+end
+
+--]]
+
+---------------------------------------------------------------------------------------------
+
+local Str = normalchar^1 / c_string
+local Space = spacechar^1 / c_space
+local Symbol = specialchar / c_string
+local Code = inticks / c_code
+
+local HeadingStart = C(hash * hash^-5) / length
+local HeadingStop = optionalspace * hash^0 * optionalspace * newline * blanklines
+local HeadingLevel = equal^3 * Cc(1)
+ + dash ^3 * Cc(2)
+
+local NormalEndline = optionalspace * newline * -(
+ blankline
+ + more
+ + HeadingStart
+ + ( line * (P("===")^3 + P("---")^3) * newline )
+ ) / c_space
+
+local LineBreak = P(" ") * NormalEndline / c_linebreak
+
+local TerminalEndline = optionalspace * newline * eof / ""
+
+local Endline = LineBreak
+ + TerminalEndline
+ + NormalEndline
+
+local AutoLinkUrl = less * C(alphanumeric^1 * P("://") * (any - (newline + more))^1) * more / c_url_link
+local AutoLinkEmail = less * C((alphanumeric + S("-_+"))^1 * P("@") * (any - (newline + more))^1) * more / c_email_link
+
+local DirectLink = direct_link_parser / c_link
+local IndirectLink = indirect_link_parser / c_link
+
+local ImageLink = exclamation * (direct_link_parser + indirect_link_parser) / c_image -- we can combine this with image ... smaller lpeg
+
+local UlOrStarLine = asterisk^4
+ + underscore^4
+ + (spaces * S("*_")^1 * #spaces) / c_string
+
+local EscapedChar = P("\\") * C(P(1 - newline)) / c_string
+
+local InlineHtml = inlinehtml / c_inline_html
+local DisplayHtml = displayhtml / c_display_html
+local HtmlEntity = hexentity / c_hex_entity
+ + decentity / c_dec_entity
+ + tagentity / c_tag_entity
+
+local NestedList = Cs(optionallyindentedline - (bullet + enumerator))^1 / nestedparser
+
+local ListBlockLine = -blankline * -(indent^-1 * (bullet + enumerator)) * optionallyindentedline
+
+local Verbatim = Cs(blanklines * (indentedline - blankline)^1) / c_verbatim
+ * (blankline^1 + eof) -- not really needed, probably capture trailing? we can do that beforehand
+
+local Blockquote = Cs((
+ ((nonindentspace * more * space^-1)/"" * linechar^0 * newline)^1
+ * ((linechar - blankline)^1 * newline)^0
+ * blankline^0
+ )^1) / c_blockquote
+
+local HorizontalRule = (lineof_asterisks + lineof_dashes + lineof_underscores) / c_hrule
+
+local Reference = define_reference_parser / ""
+
+-- could be a mini grammar
+
+local ListBlock = line * ListBlockLine^0
+local ListContinuationBlock = blanklines * indent * ListBlock
+local ListItem = Cs(ListBlock * (NestedList + ListContinuationBlock^0)) / listitem
+
+---- LeadingLines = blankline^0 / ""
+---- TrailingLines = blankline^1 * #(any) / "\n"
+
+syntax = Cs { "Document",
+
+ Document = V("Display")^0,
+
+ Display = blankline -- ^1/"\n"
+ + Blockquote
+ + Verbatim
+ + Reference
+ + HorizontalRule
+ + HeadingStart * optionalspace * Cs((V("Inline") - HeadingStop)^1) * HeadingStop / c_heading
+ + Cs((V("Inline") - Endline)^1) * newline * HeadingLevel * newline * blanklines / f_heading
+ + Cs((bullet /"" * ListItem)^1) * blanklines * -bullet / c_tightbulletlist
+ + Cs((bullet /"" * ListItem * C(blanklines))^1) / c_loosebulletlist
+ + Cs((enumerator /"" * ListItem)^1) * blanklines * -enumerator / c_tightorderedlist
+ + Cs((enumerator /"" * ListItem * C(blanklines))^1) / c_looseorderedlist
+ + DisplayHtml
+ + nonindentspace * Cs(V("Inline")^1)* newline * blankline^1 / c_paragraph
+ + V("Inline")^1,
+
+ Inline = Str
+ + Space
+ + Endline
+ + UlOrStarLine -- still needed ?
+ + doubleasterisks * -spaceornewline * Cs((V("Inline") - doubleasterisks )^1) * doubleasterisks / c_strong
+ + doubleunderscores * -spaceornewline * Cs((V("Inline") - doubleunderscores)^1) * doubleunderscores / c_strong
+ + asterisk * -spaceornewline * Cs((V("Inline") - asterisk )^1) * asterisk / c_emphasis
+ + underscore * -spaceornewline * Cs((V("Inline") - underscore )^1) * underscore / c_emphasis
+ + ImageLink
+ + DirectLink
+ + IndirectLink
+ + AutoLinkUrl
+ + AutoLinkEmail
+ + Code
+ + InlineHtml
+ + HtmlEntity
+ + EscapedChar
+ + Symbol,
+
+}
+
+---------------------------------------------------------------------------------------------
+
+local function convert(str)
+ nofruns = nofruns + 1
+ nofbytes = nofbytes + #str
+ statistics.starttiming(markdown)
+ referenceparser(str)
+ local result = c_start_document() .. nestedparser(str) .. c_stop_document()
+ statistics.stoptiming(markdown)
+ return result
+end
+
+markdown.convert = convert
+
+function markdown.typesetstring(data)
+ if data and data ~= "" then
+ local result = convert(data)
+ context.viafile(result)
+ end
+end
+
+function markdown.typesetbuffer(name)
+ markdown.typesetstring(buffers.getcontent(name))
+end
+
+function markdown.typesetfile(name)
+ local fullname = resolvers.findctxfile(name)
+ if fullname and fullname ~= "" then
+ markdown.typesetstring(io.loaddata(fullname))
+ end
+end
+
+statistics.register("markdown",function()
+ if nofruns > 0 then
+ return format("%s bytes converted, %s runs, %s html blobs, %s seconds used",
+ nofbytes, nofruns, nofhtmlblobs, statistics.elapsedtime(markdown))
+ end
+end)
+
+---------------------------------------------------------------------------------------------
+
+--~ context.starttext()
+--~ moduledata.markdown.convert(str)
+--~ context.stoptext()
+
+if not tex.jobname then
+
+ local one = [[
+Test *123*
+==========
+
+<b>BOLD *BOLD* BOLD</b>
+
+<pre>PRE <b>PRE</b> PRE</pre>
+
+
+* Test
+** Test
+* Test1
+ * Test2
+* Test
+
+Test
+====
+
+> test
+> test **123** *123*
+> test `code`
+
+test
+
+Test
+====
+
+> test
+> test
+> test
+
+test
+oeps
+
+more
+
+ code
+ code
+
+oeps
+
+[an example][a]
+
+[an example] [2]
+
+[a]: http://example.com/ "Optional *oeps* Title Here"
+[2]: http://example.com/ 'Optional Title Here'
+[3]: http://example.com/ (Optional Title Here)
+
+[an example][a]
+
+[an example] [2]
+
+[an [tricky] example](http://example.com/ "Title")
+
+[This **xx** link](http://example.net/)
+ ]]
+
+-- This snippet takes some 4 seconds in the original parser (the one that is
+-- a bit clearer from the perspective of grammars but somewhat messy with
+-- respect to the captures. In the above parser it takes .1 second. Also,
+-- in the later case only memory is the limit.
+
+ local two = [[
+Test
+====
+* Test
+** Test
+* Test
+** Test
+* Test
+
+Test
+====
+
+> test
+> test
+> test
+
+test
+
+Test
+====
+
+> test
+> test
+> test
+
+test
+ ]]
+
+ local function test(str)
+ local n = 1 -- 000
+ local t = os.clock()
+ local one = convert(str)
+ -- print("runtime",1,#str,#one,os.clock()-t)
+ str = string.rep(str,n)
+ local t = os.clock()
+ local two = convert(str)
+ print(two)
+ -- print("runtime",n,#str,#two,os.clock()-t)
+ -- print(format("==============\n%s\n==============",one))
+ end
+
+ -- test(one)
+ -- test(two)
+ -- test(io.read("*all"))
+
+
+end
diff --git a/tex/context/modules/mkiv/m-markdown.mkiv b/tex/context/modules/mkiv/m-markdown.mkiv
new file mode 100644
index 000000000..6e0036513
--- /dev/null
+++ b/tex/context/modules/mkiv/m-markdown.mkiv
@@ -0,0 +1,88 @@
+%D \module
+%D [ file=x-markdown,
+%D version=2011.07.19,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Processing MarkDown,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Modules / MarkDown Renderer}
+
+%D This module deals with markdown which is a document encoding that
+%D some \CONTEXT\ like much. It reminds me of the kind of minimal coding
+%D we used before we ran into \TEX\ and were using a somewhat simple
+%D rendering (pagination, etc) of documents. As I'm no user myself, it
+%D is up to others to provide documentation and examples.
+
+\registerctxluafile{m-markdown}{1.001}
+
+\unprotect
+
+% basic interface
+
+\definebuffer[markdown]
+
+\unexpanded\def\stopmarkdown
+ {\ctxlua{moduledata.markdown.typesetbuffer("\thedefinedbuffer{markdown}")}}
+
+\unexpanded\def\processmarkdownfile#1% maybe [] or both
+ {\ctxlua{moduledata.markdown.typesetfile("#1")}}
+
+\unexpanded\def\markdown#1% maybe [] or both
+ {\ctxlua{moduledata.markdown.typesetstring(\!!bs#1\!!es)}}
+
+% commands
+
+\defineitemgroup
+ [markdownitemize]
+
+\definetyping
+ [markdowntyping]
+
+\definetype
+ [markdowntype]
+
+\definetype
+ [markdowninlinehtml]
+
+\definetyping
+ [markdowndisplayhtml]
+
+\definedelimitedtext
+ [markdownblockquote]
+ [quotation]
+
+\definehighlight
+ [markdownemphasis]
+ [style=\em]
+
+\definehighlight
+ [markdownstrong]
+ [style=\bf]
+
+\definestructurelevels
+ [markdown]
+ [\v!chapter,
+ \v!section,
+ \v!subsection,
+ \v!subsubsection,
+ \v!subsubsubsection,
+ \v!subsubsubsubsection]
+
+\unexpanded\def\markdownrule
+ {\hairline\par}
+
+\protect
+
+\continueifinputfile{m-markdown.mkiv}
+
+\starttext
+ \startmarkdown
+ % some examples needed
+ \stopmarkdown
+\stoptext
diff --git a/tex/context/modules/mkiv/m-mathcrap.mkiv b/tex/context/modules/mkiv/m-mathcrap.mkiv
new file mode 100644
index 000000000..25efd2d5d
--- /dev/null
+++ b/tex/context/modules/mkiv/m-mathcrap.mkiv
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=m-mathcrap,
+%D version=2010.05.30,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Math Crap,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is meant for those who want to use the (incomplete and sort of useless)
+%D unicode superscripts and subscripts. We should look ahead and collapse them
+%D but I will only implement that in calcmath when the need is there. Now the
+%D spacing can be somewhat non optimal but probably that does not matter here.
+%D
+%D \startbuffer
+%D $a₀₁₂₃₄₅₆₇₈₉₋₌₊$
+%D \stopbuffer
+%D
+%D \typebuffer \blank \getbuffer \blank
+
+\unprotect
+
+\unexpanded\def\mathunicodesupercrap#1{\mathortext{{\normalsuperscript{#1}}}{\high{#1}}}
+\unexpanded\def\mathunicodesubcrap #1{\mathortext{{\normalsubscript {#1}}}{\low {#1}}}
+
+\ifdefined\installanddefineactivecharacter\else
+
+ \def\installanddefineactivecharacter #1 #2% we need this as command
+ {\normalexpanded{\noexpand\installactivecharacter \utfchar{#1} }%
+ \defineactivecharacter #1 {#2}}
+
+\fi
+
+\installanddefineactivecharacter "2070 {\mathunicodesupercrap 0}
+\installanddefineactivecharacter "00B9 {\mathunicodesupercrap 1}
+\installanddefineactivecharacter "00B2 {\mathunicodesupercrap 2}
+\installanddefineactivecharacter "00B3 {\mathunicodesupercrap 3}
+\installanddefineactivecharacter "2074 {\mathunicodesupercrap 4}
+\installanddefineactivecharacter "2075 {\mathunicodesupercrap 5}
+\installanddefineactivecharacter "2076 {\mathunicodesupercrap 6}
+\installanddefineactivecharacter "2077 {\mathunicodesupercrap 7}
+\installanddefineactivecharacter "2078 {\mathunicodesupercrap 8}
+\installanddefineactivecharacter "2079 {\mathunicodesupercrap 9}
+\installanddefineactivecharacter "207A {\mathunicodesupercrap +}
+\installanddefineactivecharacter "207B {\mathunicodesupercrap -}
+\installanddefineactivecharacter "207C {\mathunicodesupercrap =}
+\installanddefineactivecharacter "207D {\mathunicodesupercrap (}
+\installanddefineactivecharacter "207E {\mathunicodesupercrap )}
+\installanddefineactivecharacter "207F {\mathunicodesupercrap n}
+
+\installanddefineactivecharacter "2080 {\mathunicodesubcrap 0}
+\installanddefineactivecharacter "2081 {\mathunicodesubcrap 1}
+\installanddefineactivecharacter "2082 {\mathunicodesubcrap 2}
+\installanddefineactivecharacter "2083 {\mathunicodesubcrap 3}
+\installanddefineactivecharacter "2084 {\mathunicodesubcrap 4}
+\installanddefineactivecharacter "2085 {\mathunicodesubcrap 5}
+\installanddefineactivecharacter "2086 {\mathunicodesubcrap 6}
+\installanddefineactivecharacter "2087 {\mathunicodesubcrap 7}
+\installanddefineactivecharacter "2088 {\mathunicodesubcrap 8}
+\installanddefineactivecharacter "2089 {\mathunicodesubcrap 9}
+\installanddefineactivecharacter "208A {\mathunicodesubcrap +}
+\installanddefineactivecharacter "208B {\mathunicodesubcrap -}
+\installanddefineactivecharacter "208C {\mathunicodesubcrap =}
+\installanddefineactivecharacter "208D {\mathunicodesubcrap (}
+\installanddefineactivecharacter "208E {\mathunicodesubcrap )}
+\installanddefineactivecharacter "2090 {\mathunicodesubcrap A}
+\installanddefineactivecharacter "2091 {\mathunicodesubcrap E}
+\installanddefineactivecharacter "2092 {\mathunicodesubcrap O}
+\installanddefineactivecharacter "2093 {\mathunicodesubcrap X}
+%installanddefineactivecharacter "2094 {\mathunicodesubcrap ?} % SCHWAA
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv
new file mode 100644
index 000000000..ccb376e39
--- /dev/null
+++ b/tex/context/modules/mkiv/m-matrix.mkiv
@@ -0,0 +1,495 @@
+%D \module
+%D [ file=m-matrix,
+%D version=2014.11.04, % already a year older
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Matrices,
+%D author={Jeong Dalyoung \& Hans Hagen},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This code is based on a post by Dalyoung on the context list. After that
+%D we turned it into a module and improved the code a bit. Feel free to ask
+%D us for more. Once we're satisfied, a more general helper l-matrix could
+%D be made. Dalyoung does the clever bits, and Hans only cleanes up and
+%D optimizes a bit.
+
+% \registerctxluafile{l-matrix}{1.001} % not yet
+
+\startmodule[matrix]
+
+\startluacode
+
+local settings_to_hash = utilities.parsers.settings_to_hash
+local formatters = string.formatters
+local copy = table.copy
+local insert = table.insert
+local remove = table.remove
+
+local matrix = { }
+moduledata.matrix = matrix
+
+local f_matrix_slot = formatters["%s_{%s%s}"]
+
+function matrix.symbolic(sym, x, y, nx ,ny) -- symMatrix("a", "m", "n")
+ local nx = nx or 2
+ local ny = ny or nx
+ local function filled(i,y)
+ local mrow = { }
+ for j=1,nx do
+ mrow[#mrow+1] = f_matrix_slot(sym,i,j)
+ end
+ mrow[#mrow+1] = "\\cdots"
+ mrow[#mrow+1] = f_matrix_slot(sym,i,y)
+ return mrow
+ end
+ local function dummy()
+ local mrow = { }
+ for j=1,nx do
+ mrow[#mrow+1] = "\\vdots"
+ end
+ mrow[#mrow+1] = "\\ddots"
+ mrow[#mrow+1] = "\\vdots"
+ return mrow
+ end
+ --
+ local mm = { }
+ for i=1,ny do
+ mm[i] = filled(i,y)
+ end
+ mm[#mm+1] = dummy()
+ mm[#mm+1] = filled(x,y)
+ return mm
+end
+
+-- todo: define a matrix at the tex end so that we have more control
+
+local fences_p = {
+ left = "\\left(\\,",
+ right = "\\,\\right)",
+}
+
+local fences_b = {
+ left = "\\left[\\,",
+ right = "\\,\\right]",
+}
+
+function matrix.typeset(m,options)
+ local options = settings_to_hash(options or "")
+ context.startmatrix(options.determinant and fences_b or fences_p)
+ for i=1, #m do
+ local mi = m[i]
+ for j=1,#mi do
+ context.NC(mi[j])
+ end
+ context.NR()
+ end
+ context.stopmatrix()
+end
+
+-- interchange two rows (i-th, j-th)
+
+function matrix.swap(t,i,j)
+ t[i], t[j] = t[j], t[i]
+end
+
+-- replace i-th row with factor * (i-th row)
+
+function matrix.multiply(m,i,factor)
+ local mi = m[i]
+ for k=1,#mi do
+ mi[k] = factor * mi[k]
+ end
+ return m
+end
+
+-- scalar product "factor * m"
+
+function matrix.scalar(m, factor)
+ for i=1,#m do
+ local mi = m[i]
+ for j=1,#mi do
+ mi[j] = factor * mi[j]
+ end
+ end
+ return m
+end
+
+-- replace i-th row with i-th row + factor * (j-th row)
+
+function matrix.sumrow(m,i,j,factor)
+ local mi = m[i]
+ local mj = m[j]
+ for k=1,#mi do
+ mi[k] = mi[k] + factor * mj[k]
+ end
+end
+
+-- transpose of a matrix
+
+function matrix.transpose(m)
+ local t = { }
+ for j=1,#m[1] do
+ local r = { }
+ for i=1,#m do
+ r[i] = m[i][j]
+ end
+ t[j] = r
+ end
+ return t
+end
+
+-- inner product of two vectors
+
+function matrix.inner(u,v)
+ local nu = #u
+ if nu == 0 then
+ return 0
+ end
+ local nv = #v
+ if nv ~= nu then
+ return 0
+ end
+ local result = 0
+ for i=1,nu do
+ result = result + u[i] * v[i]
+ end
+ return result
+end
+
+-- product of two matrices
+
+function matrix.product(m1,m2)
+ local product = { }
+ if #m1[1] == #m2 then
+ for i=1,#m1 do
+ local m1i = m1[i]
+ local mrow = { }
+ for j=1,#m2[1] do
+ local temp = 0
+ for k=1,#m1[1] do
+ temp = temp + m1i[k] * m2[k][j]
+ end
+ mrow[j] = temp
+ end
+ product[i] = mrow
+ end
+ end
+ return product
+end
+
+local function uppertri(m,sign)
+ local temp = copy(m)
+ for i=1,#temp-1 do
+ local pivot = temp[i][i]
+ if pivot == 0 then
+ local pRow = i +1
+ while temp[pRow][i] == 0 do
+ pRow = pRow + 1
+ if pRow > #temp then -- if there is no nonzero number
+ return temp
+ end
+ end
+ temp[i], temp[pRow] = temp[pRow], temp[i]
+ if sign then
+ sign = -sign
+ end
+ end
+ local mi = temp[i]
+ for k=i+1, #temp do
+ local factor = -temp[k][i]/mi[i]
+ local mk = temp[k]
+ for l=i,#mk do
+ mk[l] = mk[l] + factor * mi[l]
+ end
+ end
+ end
+ if sign then
+ return temp, sign
+ else
+ return temp
+ end
+end
+
+matrix.uppertri = uppertri
+
+function matrix.determinant(m)
+ if #m == #m[1] then
+ local d = 1
+ local t, s = uppertri(m,1)
+ for i=1,#t do
+ d = d * t[i][i]
+ end
+ return s*d
+ else
+ return 0
+ end
+end
+
+local function rowechelon(m,r)
+ local temp = copy(m)
+ local pRow = 1
+ local pCol = 1
+ while pRow <= #temp do
+ local pivot = temp[pRow][pCol]
+ if pivot == 0 then
+ local i = pRow
+ local n = #temp
+ while temp[i][pCol] == 0 do
+ i = i + 1
+ if i > n then
+ -- no nonzero number in a column
+ pCol = pCol + 1
+ if pCol > #temp[pRow] then
+ -- there is no nonzero number in a row
+ return temp
+ end
+ i = pRow
+ end
+ end
+ temp[pRow], temp[i] = temp[i], temp[pRow]
+ end
+ local row = temp[pRow]
+ pivot = row[pCol]
+ for l=pCol,#row do
+ row[l] = row[l]/pivot
+ end
+
+ if r == 1 then
+ -- make the "reduced row echelon form"
+ local row = temp[pRow]
+ for k=1,pRow-1 do
+ local current = temp[k]
+ local factor = -current[pCol]
+ local mk = current
+ for l=pCol,#mk do
+ mk[l] = mk[l] + factor * row[l]
+ end
+ end
+ end
+ -- just make the row echelon form
+ local row = temp[pRow]
+ for k=pRow+1, #temp do
+ local current = temp[k]
+ local factor = -current[pCol]
+ local mk = current
+ for l=pCol,#mk do
+ mk[l] = mk[l] + factor * row[l]
+ end
+ end
+ pRow = pRow + 1
+ pCol = pCol + 1
+
+ if pRow > #temp or pCol > #temp[1] then
+ pRow = #temp + 1
+ end
+ end
+ return temp
+end
+
+matrix.rowechelon = rowechelon
+matrix.rowEchelon = rowechelon
+
+-- solve the linear equation m X = c
+
+local function solve(m,c)
+ local n = #m
+ if n ~= #c then
+ return copy(m)
+ end
+ local newm = copy(m)
+ local temp = copy(c)
+ for i=1,n do
+ insert(newm[i],temp[i])
+ end
+ return rowechelon(newm,1)
+end
+
+matrix.solve = solve
+
+-- find the inverse matrix of m
+
+local function inverse(m)
+ local n = #m
+ local temp = copy(m)
+ if n ~= #m[1] then
+ return temp
+ end
+ for i=1,n do
+ for j=1,n do
+ insert(temp[i],j == i and 1 or 0)
+ end
+ end
+ temp = rowechelon(temp,1)
+ for i=1,n do
+ for j=1,n do
+ remove(temp[i], 1)
+ end
+ end
+ return temp
+end
+
+matrix.inverse = inverse
+
+\stopluacode
+
+\stopmodule
+
+\unexpanded\def\ctxmodulematrix#1{\ctxlua{moduledata.matrix.#1}}
+
+\continueifinputfile{m-matrix.mkiv}
+
+\starttext
+
+\startluacode
+document.DemoMatrixA = {
+ { 0, 2, 4, -4, 1 },
+ { 0, 0, 2, 3, 4 },
+ { 2, 2, -6, 2, 4 },
+ { 2, 0, -6, 9, 7 },
+ { 2, 3, 4, 5, 6 },
+ { 6, 6, -6, 6, 6 },
+}
+
+document.DemoMatrixB = {
+ { 0, 2, 4, -4, 1 },
+ { 0, 0, 2, 3, 4 },
+ { 2, 2, -6, 2, 4 },
+ { 2, 0, -6, 9, 7 },
+ { 2, 2, -6, 2, 4 },
+ { 2, 2, -6, 2, 4 },
+}
+\stopluacode
+
+\startsubject[title={A symbolic matrix}]
+
+\ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n"))}
+\ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n", 4, 8))}
+
+\stopsubject
+
+\startsubject[title={Swap two rows (2 and 4)}]
+
+\startluacode
+moduledata.matrix.typeset(document.DemoMatrixA)
+context.blank()
+moduledata.matrix.swap(document.DemoMatrixA, 2, 4)
+context.blank()
+moduledata.matrix.typeset(document.DemoMatrixA)
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Multiply $3 \times r_2$}]
+
+\startluacode
+moduledata.matrix.typeset(document.DemoMatrixA)
+context.blank()
+moduledata.matrix.typeset(moduledata.matrix.multiply(document.DemoMatrixA, 2, 3))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Row 2 + $3 \times r_4$}]
+
+\startluacode
+moduledata.matrix.typeset(document.DemoMatrixA)
+context.blank()
+moduledata.matrix.sumrow(document.DemoMatrixA, 2, 3, 4)
+context.blank()
+moduledata.matrix.typeset(document.DemoMatrixA)
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Transpose a matrix}]
+
+\startluacode
+moduledata.matrix.typeset(document.DemoMatrixA)
+context.blank()
+moduledata.matrix.typeset(moduledata.matrix.transpose(document.DemoMatrixA))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={The inner product of two vectors}]
+
+\startluacode
+context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2 }))
+context.blank()
+context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 }))
+\stopluacode
+
+\startsubject[title={The product of two matrices}]
+
+\startluacode
+moduledata.matrix.typeset(document.DemoMatrixA)
+context.blank()
+moduledata.matrix.typeset(moduledata.matrix.product(document.DemoMatrixA,document.DemoMatrixA))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={An Upper Triangular Matrix}]
+
+\ctxmodulematrix{typeset(moduledata.matrix.uppertri(document.DemoMatrixB))}
+
+\startsubject[title={A determinant}]
+
+\startluacode
+local m = {
+ { 1, 2, 4 },
+ { 0, 0, 2 },
+ { 2, 2, -6 },
+}
+context(moduledata.matrix.determinant(m))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Row echelon form}]
+
+\startluacode
+local m = {
+ { 1, 3, -2, 0, 2, 0, 0 },
+ { 2, 6, -5, -2, 4, -3, -1 },
+ { 0, 0, 5, 10, 0, 15, 5 },
+ { 2, 6, 0, 8, 4, 18, 6 },
+}
+
+moduledata.matrix.typeset(m)
+moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Solving linear equation}]
+
+\startluacode
+local m = {
+ { 1, 3, -2, 0 },
+ { 2, 0, 1, 2 },
+ { 6, -5, -2, 4 },
+ { -3, -1, 5, 10 },
+}
+
+local c = { 5, 2, 6, 8 }
+
+moduledata.matrix.typeset(moduledata.matrix.solve(m,c))
+\stopluacode
+
+\stopsubject
+
+\startsubject[title={Inverse matrix}]
+
+\startcombination[2*1]
+ {\ctxlua{moduledata.matrix.typeset { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } }}} {}
+ {\ctxlua{moduledata.matrix.typeset(moduledata.matrix.inverse { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } })}} {}
+\stopcombination
+
+\stopsubject
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-mkii.mkiv b/tex/context/modules/mkiv/m-mkii.mkiv
new file mode 100644
index 000000000..dcfd29d20
--- /dev/null
+++ b/tex/context/modules/mkiv/m-mkii.mkiv
@@ -0,0 +1,21 @@
+% todo
+
+\unprotect
+
+\writestatus\m!system{loading some mkii compatibility hacks}
+
+% Compatibility for font-ini
+
+\let\normalxi=\xi
+
+\definebodyfontswitch [xii] [\!!twelvepoint]
+\definebodyfontswitch [xi] [\!!elevenpoint]
+\definebodyfontswitch [x] [\!!tenpoint]
+\definebodyfontswitch [ix] [\!!ninepoint]
+\definebodyfontswitch [viii] [\!!eightpoint]
+\definebodyfontswitch [vii] [\!!sevenpoint]
+\definebodyfontswitch [vi] [\!!sixpoint]
+
+\unexpanded\def\xi{\ifmmode\normalxi\else\elevenpoint\fi}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-mkivhacks.mkiv b/tex/context/modules/mkiv/m-mkivhacks.mkiv
new file mode 100644
index 000000000..3ed002e1d
--- /dev/null
+++ b/tex/context/modules/mkiv/m-mkivhacks.mkiv
@@ -0,0 +1,50 @@
+%D \module
+%D [ file=m-mkivhacks,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Temporary Compatilibility Hacks,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D For Aditya, who needed it for his thesis.
+
+\startluacode
+ -- -- a lot or work
+ --
+ -- mathematics.slots.euler = {
+ -- [0x03B1] = { "mr", 0x0B }, -- alpha
+ -- }
+ --
+ -- mathematics.slots.euler = table.merge(mathematics.slots.traditional,mathematics.slots.euler)
+ --
+ -- versus a quick hack
+
+ document.hacks = document.hacks or { }
+
+ function document.hacks()
+ mathematics.families.lcgreek = mathematics.families.mr
+ mathematics.families.ucgreek = mathematics.families.mr
+ mathematics.families.vargreek = mathematics.families.mr
+
+ mathematics.define(mathematics.slots.euler)
+ end
+\stopluacode
+
+% \usemodule[mkivhacks] \setups{eulermath}
+% \definetypeface[modern][mm][math][euler][default]
+% \usemathcollection[eul]
+% \switchtobodyfont[modern,11pt]
+% \starttext
+% $\alpha$
+% \stoptext
+
+\startsetups eulermath
+ \ctxlua{document.hacks()}
+\stopsetups
+
+\endinput
diff --git a/tex/context/modules/mkiv/m-morse.mkvi b/tex/context/modules/mkiv/m-morse.mkvi
new file mode 100644
index 000000000..a2c20dff7
--- /dev/null
+++ b/tex/context/modules/mkiv/m-morse.mkvi
@@ -0,0 +1,273 @@
+%D \module
+%D [ file=m-morse,
+%D version=2010.12.10,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Morse,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: act upon the node list
+% make it a buffer operation
+% nice in cld manual
+
+\startluacode
+
+moduledata.morse = moduledata.morse or { }
+local morse = moduledata.morse
+
+local utfcharacters, gsub = string.utfcharacters, string.gsub
+local ucchars, shchars = characters.ucchars, characters.shchars
+
+local codes = {
+
+ ["A"] = "·—",
+ ["B"] = "—···",
+ ["C"] = "—·—·",
+ ["D"] = "—··",
+ ["E"] = "·",
+ ["F"] = "··—·",
+ ["G"] = "——·",
+ ["H"] = "····",
+ ["I"] = "··",
+ ["J"] = "·———",
+ ["K"] = "—·—",
+ ["L"] = "·—··",
+ ["M"] = "——",
+ ["N"] = "—·",
+ ["O"] = "———",
+ ["P"] = "·——·",
+ ["Q"] = "——·—",
+ ["R"] = "·—·",
+ ["S"] = "···",
+ ["T"] = "—",
+ ["U"] = "··—",
+ ["V"] = "···—",
+ ["W"] = "·——",
+ ["X"] = "—··—",
+ ["Y"] = "—·——",
+ ["Z"] = "——··",
+
+ ["0"] = "—————",
+ ["1"] = "·————",
+ ["2"] = "··———",
+ ["3"] = "···——",
+ ["4"] = "····—",
+ ["5"] = "·····",
+ ["6"] = "—····",
+ ["7"] = "——···",
+ ["8"] = "———··",
+ ["9"] = "————·",
+
+ ["."] = "·—·—·—",
+ [","] = "——··——",
+ [":"] = "———···",
+ [";"] = "—·—·—",
+
+ ["?"] = "··——··",
+ ["!"] = "—·—·——",
+
+ ["-"] = "—····—",
+ ["/"] = "—··—· ",
+
+ ["("] = "—·——·",
+ [")"] = "—·——·—",
+
+ ["="] = "—···—",
+ ["@"] = "·——·—·",
+
+ ["'"] = "·————·",
+ ['"'] = "·—··—·",
+
+ ["À"] = "·——·—",
+ ["Å"] = "·——·—",
+ ["Ä"] = "·—·—",
+ ["Æ"] = "·—·—",
+ ["Ç"] = "—·—··",
+ ["É"] = "··—··",
+ ["È"] = "·—··—",
+ ["Ñ"] = "——·——",
+ ["Ö"] = "———·",
+ ["Ø"] = "———·",
+ ["Ü"] = "··——",
+ ["ß"] = "··· ···",
+
+}
+
+morse.codes = codes
+
+local fallbackself = false
+
+local function codefallback(t,k)
+ if k then
+ local u = ucchars[k]
+ local v = rawget(t,u) or rawget(t,shchars[u]) or false
+ t[k] = v
+ return v
+ elseif fallbackself then
+ return k
+ else
+ return false
+ end
+end
+
+table.setmetatableindex(codes,codefallback)
+
+local MorseBetweenWords = context.MorseBetweenWords
+local MorseBetweenCharacters = context.MorseBetweenCharacters
+local MorseLong = context.MorseLong
+local MorseShort = context.MorseShort
+local MorseSpace = context.MorseSpace
+local MorseUnknown = context.MorseUnknown
+
+local function toverbose(str)
+ str = gsub(str,"%s*+%s*","+")
+ str = gsub(str,"%s+"," ")
+ local done = false
+ for m in utfcharacters(str) do
+ if done then
+ MorseBetweenCharacters()
+ end
+ if m == "·" or m == "." then
+ MorseShort()
+ done = true
+ elseif m == "—" or m == "-" then
+ MorseLong()
+ done = true
+ elseif m == " " then
+ if done then
+ MorseBetweenCharacters()
+ end
+ done = false
+ elseif m == "+" then
+ MorseBetweenWords()
+ done = false
+ else
+ MorseUnknown(m)
+ end
+ end
+end
+
+local function toregular(str)
+ local inmorse = false
+ for s in utfcharacters(str) do
+ local m = codes[s]
+ if m then
+ if inmorse then
+ MorseBetweenWords()
+ else
+ inmorse = true
+ end
+ local done = false
+ for m in utfcharacters(m) do
+ if done then
+ MorseBetweenCharacters()
+ else
+ done = true
+ end
+ if m == "·" then
+ MorseShort()
+ elseif m == "—" then
+ MorseLong()
+ elseif m == " " then
+ MorseBetweenCharacters()
+ end
+ end
+ inmorse = true
+ elseif s == "\n" or s == " " then
+ MorseSpace()
+ inmorse = false
+ else
+ if inmorse then
+ MorseBetweenWords()
+ else
+ inmorse = true
+ end
+ MorseUnknown(s)
+ end
+ end
+end
+
+local function tomorse(str,verbose)
+ if verbose then
+ toverbose(str)
+ else
+ toregular(str)
+ end
+end
+
+morse.tomorse = tomorse
+
+function morse.filetomorse(name,verbose)
+ tomorse(resolvers.loadtexfile(name),verbose)
+end
+
+function morse.showtable()
+ context.starttabulate { "|l|l|" } -- { "|l|l|l|" }
+ for k, v in table.sortedpairs(codes) do
+ context.NC() context(k)
+ -- context.NC() context(v)
+ context.NC() tomorse(v,true)
+ context.NC() context.NR()
+ end
+ context.stoptabulate()
+end
+
+\stopluacode
+
+\unprotect
+
+% todo: \setupmorse, but probably it's not worth the trouble.
+
+\def\MorseWidth {0.4em}
+\def\MorseHeight {0.2em}
+%def\MorseShort {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=\dimexpr\MorseWidth]}
+%def\MorseLong {\dontleavehmode\blackrule[\c!height=\MorseHeight,\c!width=3\dimexpr\MorseWidth]}
+\def\MorseShort {\dontleavehmode\vrule\!!width \dimexpr\MorseWidth\!!height\MorseHeight\!!depth\zeropoint\relax}
+\def\MorseLong {\dontleavehmode\vrule\!!width3\dimexpr\MorseWidth\!!height\MorseHeight\!!depth\zeropoint\relax}
+\def\MorseBetweenCharacters {\kern\MorseWidth}
+\def\MorseBetweenWords {\hskip3\dimexpr\MorseWidth\relax}
+\def\MorseSpace {\hskip7\dimexpr\MorseWidth\relax}
+\def\MorseUnknown #text{[\detokenize{#text}]}
+
+\unexpanded\def\MorseCode #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es,true)}}
+\unexpanded\def\MorseString #text{\ctxlua{moduledata.morse.tomorse(\!!bs#text\!!es)}}
+\unexpanded\def\MorseFile #text{\ctxlua{moduledata.morse.filetomorse("#text")}}
+\unexpanded\def\MorseTable {\ctxlua{moduledata.morse.showtable()}}
+
+\let\Morse \MorseString
+
+%def\MorseShort {·}
+%def\MorseLong {—}
+
+\protect
+
+\continueifinputfile{m-morse.mkvi}
+
+\starttext
+
+\MorseTable
+
+\startlines
+\MorseCode{—·—· ——— —· — · —··— —+—— —·— ·· ···—}
+\MorseCode{—·—· ——— —· — · —··— — + —— —·— ·· ···—}
+\Morse{ÀÁÂÃÄÅàáâãäå}
+\Morse{ÆÇæç}
+\Morse{ÈÉÊËèéêë}
+\Morse{ÌÍÎÏìíîï}
+\Morse{Ññ}
+\Morse{ÒÓÔÕÖòóôõö}
+\Morse{Øø}
+\Morse{ÙÚÛÜùúû}
+\Morse{Ýýÿ}
+\Morse{ß}
+\Morse{Ţţ}
+\stoplines
+
+\Morse{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-narrowtt.mkiv b/tex/context/modules/mkiv/m-narrowtt.mkiv
new file mode 100644
index 000000000..7d497a02f
--- /dev/null
+++ b/tex/context/modules/mkiv/m-narrowtt.mkiv
@@ -0,0 +1,39 @@
+%D \module
+%D [ file=m-narrowtt,
+%D version=2005.09.08,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Narrow Verbatim,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Test file
+%D
+%D \starttyping
+%D \startTEX
+%D \usemodule[narrowtt]
+%D \starttext
+%D \starttyping
+%D Test test test.
+%D \stoptyping
+%D test \type {test} test \type{test} test
+%D \starttyping
+%D Test test test.
+%D \stoptyping
+%D \stoptext
+%D \stopTEX
+
+\unprotect
+
+\definetypeface
+ [narrowtt] [tt]
+ [mono] [modern-condensed] [\s!default] [\s!features=\s!none]
+
+\definetyping[n\v!typing] \setuptyping[n\v!typing][style=\narrowtt]
+\definetype [n\v!type] \setuptype [n\v!type] [style=\narrowtt]
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-nodechart.lua b/tex/context/modules/mkiv/m-nodechart.lua
new file mode 100644
index 000000000..4f2740ef4
--- /dev/null
+++ b/tex/context/modules/mkiv/m-nodechart.lua
@@ -0,0 +1,177 @@
+if not modules then modules = { } end modules ['m-nodechart'] = {
+ version = 1.001,
+ comment = "companion to m-nodechart.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local format = string.format
+local points = number.nopts
+local ptfactor = number.dimenfactors.pt
+
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
+local penaltycodes = nodes.penaltycodes
+local gluecodes = nodes.gluecodes
+local whatsitcodes = nodes.whatsitcodes
+
+moduledata.charts = moduledata.charts or { }
+moduledata.charts.nodes = moduledata.charts.nodes or { }
+
+local formatters = { }
+
+-- subtype font char lang left right uchyph components xoffset yoffset width height depth
+
+function formatters.glyph(n,comment)
+ return format("\\doFLOWglyphnode{%s}{%s}{%s}{%s}{U+%05X}",comment,n.subtype,n.font,n.char,n.char)
+end
+
+-- pre post replace
+
+function formatters.disc(n,comment)
+ return format("\\doFLOWdiscnode{%s}{%s}",comment,n.subtype)
+end
+
+-- subtype kern
+
+function formatters.kern(n,comment)
+ -- return format("\\doFLOWkernnode{%s}{%s}{%s}",comment,kerncodes[n.subtype],points(n.kern))
+ return format("\\doFLOWkernnode{%s}{%s}{%.4f}",comment,kerncodes[n.subtype],n.kern*ptfactor)
+end
+
+-- subtype penalty
+
+function formatters.penalty(n,comment)
+ return format("\\doFLOWpenaltynode{%s}{%s}{%s}",comment,"penalty",n.penalty)
+end
+
+-- subtype width leader spec (stretch shrink ...
+
+function formatters.glue(n,comment)
+ local s = n.spec
+ -- return format("\\doFLOWgluenode{%s}{%s}{%s}{%s}{%s}",comment,gluecodes[n.subtype],points(s.width),points(s.stretch),points(s.shrink))
+ return format("\\doFLOWgluenode{%s}{%s}{%.4f}{%.4f}{%.4f}",comment,gluecodes[n.subtype],s.width*ptfactor,s.stretch*ptfactor,s.shrink*ptfactor)
+end
+
+-- subtype width leader spec (stretch shrink ...
+
+function formatters.whatsit(n,comment)
+ return whatsitcodes[n.id] or "unknown whatsit"
+end
+
+function formatters.dir(n,comment)
+ return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"dir",n.dir)
+end
+
+function formatters.localpar(n,comment)
+ return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"localpar",n.dir)
+end
+
+-- I will make a dedicated set of shapes for this.
+
+local shapes = {
+ glyph = "procedure",
+ disc = "procedure",
+ kern = "action",
+ penalty = "action",
+ glue = "action",
+}
+
+local function flow_nodes_to_chart(specification)
+ local head = specification.head
+ local box = specification.box
+ local comment = specification.comment or ""
+ local x = specification.x or 1
+ local y = specification.y or 0
+ --
+ if box then
+ box = tex.getbox(tonumber(box))
+ head = box and box.list
+ end
+ --
+ local current = head
+ --
+ while current do
+ local nodecode = nodecodes[current.id]
+ local formatter = formatters[nodecode]
+ local shape = shapes[nodecode]
+ y = y + 1
+ local next = current.next
+ commands.flow_start_cell { shape = { framecolor = "nodechart:" .. nodecode } }
+ commands.flow_set_name(tostring(current))
+ commands.flow_set_location(x,y)
+ if shape then
+ commands.flow_set_shape(shape)
+ end
+ if formatter then
+ commands.flow_set_text("node",formatter(current,comment))
+ else
+ commands.flow_set_text("node",nodecode)
+ end
+ if next then
+ commands.flow_set_connection("bt","",tostring(next))
+ end
+ if nodecode == "glyph" then
+ local components = current.components
+ if components then
+ commands.flow_set_connection("rl","",tostring(components))
+ commands.flow_stop_cell()
+ n = flow_nodes_to_chart { head = components, comment = "component",x = x+2, y = y-1 }
+ else
+ commands.flow_stop_cell()
+ end
+ elseif nodecode == "disc" then
+ local pre = current.pre
+ local pos = current.post
+ local rep = current.replace
+ if pre and not rep and not rep then
+ if pre then
+ commands.flow_set_connection("rl","",tostring(pre))
+ end
+ commands.flow_stop_cell()
+ if pre then
+ n = flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 }
+ end
+ else
+ if pre then
+ commands.flow_set_connection("+rl","",tostring(pre))
+ end
+ if rep then
+ commands.flow_set_connection("rl","",tostring(rep))
+ end
+ if pos then
+ commands.flow_set_connection("-rl","",tostring(pos))
+ end
+ commands.flow_stop_cell()
+ if pre then
+ n = flow_nodes_to_chart{ head = pre, comment = "prebreak", x = x+1, y = y-2 }
+ end
+ if rep then
+ n = flow_nodes_to_chart{ head = rep, comment = "replacement", x = x+1, y = y-1 }
+ end
+ if pos then
+ n = flow_nodes_to_chart{ head = pos, comment = "postbreak", x = x+1, y = y }
+ end
+ end
+ elseif nodecode == "hlist" then
+ local list = current.list
+ if list then
+ commands.flow_set_connection("rl","",tostring(list))
+ commands.flow_stop_cell()
+ n = flow_nodes_to_chart { head = list, comment = "list", x = x+2, y = y-1 }
+ else
+ commands.flow_stop_cell()
+ end
+ else
+ commands.flow_stop_cell()
+ end
+ current = next
+ end
+end
+
+function moduledata.charts.nodes.chart(specification)
+ commands.flow_start_chart(specification.name)
+ flow_nodes_to_chart(specification)
+ commands.flow_stop_chart()
+end
diff --git a/tex/context/modules/mkiv/m-nodechart.mkvi b/tex/context/modules/mkiv/m-nodechart.mkvi
new file mode 100644
index 000000000..c9d985850
--- /dev/null
+++ b/tex/context/modules/mkiv/m-nodechart.mkvi
@@ -0,0 +1,125 @@
+%D \module
+%D [ file=m-nodechart,
+%D version=2011.11.11, % nos sure when it started, needed for fonts-mkiv
+%D title=\CONTEXT\ Modules,
+%D subtitle=Node Visualization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\registerctxluafile{m-nodechart}{1.001}
+
+\usemodule[chart]
+
+\unprotect
+
+\def\enspaceminus{\hskip.5em minus .25em\relax}
+
+\starttexdefinition unexpanded doFLOWglyphnode #comment #subtype #font #char #unicode
+ \dontleavehmode\hbox{\bf\setstrut\strut \doifsomething{#comment}{#comment\enspaceminus:\enspaceminus}glyph #subtype}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut font\enspaceminus#font:\enspace#unicode:\enspaceminus\setfontofid{#font}\char#char}
+\stoptexdefinition
+
+\starttexdefinition unexpanded doFLOWdiscnode #comment #subtype
+ \dontleavehmode\hbox{\bf\setstrut\strut disc}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut}
+\stoptexdefinition
+
+\starttexdefinition unexpanded doFLOWkernnode #comment #subtype #kern
+ \dontleavehmode\hbox{\bf\setstrut\strut#subtype}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut#kern}
+\stoptexdefinition
+
+\starttexdefinition unexpanded doFLOWpenaltynode #comment #subtype #penalty
+ \dontleavehmode\hbox{\bf\setstrut\strut#subtype}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut#penalty}
+\stoptexdefinition
+
+\starttexdefinition unexpanded doFLOWgluenode #comment #subtype #width #shrink #stretch
+ \dontleavehmode\hbox{\bf\setstrut\strut#subtype}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut#width\enspaceminus-\enspaceminus#shrink\enspaceminus+\enspaceminus#stretch}
+\stoptexdefinition
+
+\starttexdefinition unexpanded doFLOWdirnode #comment #subtype #direction
+ \dontleavehmode\hbox{\bf\setstrut\strut#subtype}
+ \vss
+ \dontleavehmode\hbox{\tx\setstrut\strut#direction}
+\stoptexdefinition
+
+\defineframed
+ [flowcell:node]
+ [flowcell:base]
+ [\c!top=\vss,
+ \c!bottom=\vss,
+ \c!align=\v!middle,
+ \c!foregroundstyle=\tt]
+
+% this is a temporary interface ... we will have instances and optional settings
+
+\unexpanded\def\boxtoFLOWchart[#name]#box%
+ {\ctxlua{moduledata.charts.nodes.chart {
+ name = "#name",
+ box = \number#box,
+ }}}
+
+\unexpanded\def\nextboxtoFLOWchart[#name]%
+ {\dowithnextbox{\boxtoFLOWchart[#name]\nextbox}}
+
+\unexpanded\def\hboxtoFLOWchart[#name]%
+ {\nextboxtoFLOWchart[#name]\hbox}
+
+\unexpanded\def\vboxtoFLOWchart[#name]%
+ {\nextboxtoFLOWchart[#name]\vbox}
+
+\protect
+
+\continueifinputfile{m-nodechart.mkvi}
+
+\definecolor[nodechart:glyph][darkred]
+
+\setupbodyfont[dejavu,10pt]
+
+\starttext
+
+\startTEXpage[offset=10pt]
+
+ \hboxtoFLOWchart[dummy]{an affil\discretionary{-}{-}{!}iation}
+
+ \FLOWchart[dummy][width=14em,height=3em,dx=1em,dy=.75em,hcompact=yes]
+
+\stopTEXpage
+
+\startTEXpage[offset=10pt]
+
+ \hboxtoFLOWchart[dummy]{an affiliation}
+
+ \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes]
+
+\stopTEXpage
+
+\startTEXpage[offset=10pt]
+
+ \hboxtoFLOWchart[dummy]{\nl effe fijn fietsen}
+
+ \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes]
+
+\stopTEXpage
+
+\startTEXpage[offset=10pt]
+
+ \hboxtoFLOWchart[dummy]{\righttoleft t\kern 1pt est}
+
+ \FLOWchart[dummy][width=14em,height=3em,dx=.5em,dy=.75em,hcompact=yes]
+
+\stopTEXpage
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv b/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv
new file mode 100644
index 000000000..55b4ab259
--- /dev/null
+++ b/tex/context/modules/mkiv/m-ntb-to-xtb.mkiv
@@ -0,0 +1,5 @@
+\loadmkvifile{tabl-xnt}
+
+\mapTABLEtoxtable
+
+\endinput
diff --git a/tex/context/modules/mkiv/m-obsolete.mkiv b/tex/context/modules/mkiv/m-obsolete.mkiv
new file mode 100644
index 000000000..2d4518181
--- /dev/null
+++ b/tex/context/modules/mkiv/m-obsolete.mkiv
@@ -0,0 +1,5 @@
+\unprotect
+
+\writestatus\m!system{skipping obsolete module}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-oldfun.mkiv b/tex/context/modules/mkiv/m-oldfun.mkiv
new file mode 100644
index 000000000..3f2ec0263
--- /dev/null
+++ b/tex/context/modules/mkiv/m-oldfun.mkiv
@@ -0,0 +1,714 @@
+%D \module
+%D [ file=m-oldfun, % was: supp-fun
+%D version=1995.10.10,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Fun Stuff,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D Beware, these macros wil be replaced and at some point this
+%D module will not be preloaded any more.
+
+%D This module implements some typographics tricks that can
+%D be fun when designing document layouts. The examples use
+%D macros that are typical to \CONTEXT, but non \CONTEXT\
+%D users can use the drop caps and first line treatment
+%D macros without problems. This module will be extended
+%D when the need for more of such tricks arises.
+
+\writestatus{loading}{ConTeXt Support Macros / Fun Stuff}
+
+%D \macros
+%D {DroppedCaps, DroppedString, DroppedIndent, DroppedLines}
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[green]} {SerifBold}
+%D {\the\dimexpr2.2\baselineskip} {2pt} {\the\baselineskip} {2}
+%D Let's start
+%D \stopbuffer
+%D
+%D \getbuffer with dropped caps, those blown up first
+%D characters of a paragraph. It's hard to implement a general
+%D mechanism that suits all situations, but dropped caps are so
+%D seldomly used that we can permit ourselves a rather user
+%D unfriendly implementation.
+%D
+%D \typebuffer
+%D
+%D As we will see, there are 7 different settings involved. The
+%D first argument takes a command that is used to do whatever
+%D fancy things we want to do, but normally this one will be
+%D empty. The second argument takes the font. Because we're
+%D dealing with something very typographic, there is no real
+%D reason to adopt complicated font switching schemes, a mere
+%D name will do. Font encodings can bring no harm, because the
+%D alphanumeric characters are nearly always located at their
+%D natural position in the encoding vector.
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[red]} {SerifBold}
+%D {\the\baselineskip} {0pt} {0pt} {1}
+%D This simple
+%D \stopbuffer
+%D
+%D \getbuffer case shows us what happens when we apply minimal
+%D values. Here we used:
+%D
+%D \typebuffer
+%D
+%D \startbuffer
+%D \DroppedCaps
+%D {\color[red]} {SerifBold}
+%D {\the\dimexpr2\baselineskip} {0pt} {\the\baselineskip} {2}
+%D Is this ugly
+%D \stopbuffer
+%D
+%D \getbuffer example the third argument tells
+%D this macro that we want a dropped capital scaled to the
+%D baseline distance. The two zero point arguments are the
+%D horizontal and vertical offsets and the last arguments
+%D determines the hanging indentation. In this paragraph we
+%D set the height to two times the baselinedistance and use
+%D two hanging lines:
+%D
+%D \typebuffer
+%D
+%D Here, the first character is moved down one baseline. Here
+%D we also see why the horizontal offset is important. The
+%D first example (showing the~L) sets this to a few points and
+%D also used a slightly larger height.
+%D
+%D Of course common users (typist) are not supposed to see this
+%D kind of fuzzy definitions, but fortunately \TEX\ permits us
+%D to hide them in macros. Using a macro also enables us to
+%D garantee consistency throughout the document:
+%D
+%D \startbuffer
+%D \def\MyDroppedCaps%
+%D {\DroppedCaps
+%D {\color[green]} {SerifBold}
+%D {\the\dimexpr5\baselineskip} {3pt} {\the\dimexpr3\baselineskip} {4}}
+%D
+%D \MyDroppedCaps The implementation
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \getbuffer of the general macro is rather simple and only
+%D depends on the arguments given and the dimensions of the
+%D strut box. We explicitly load the font, which is no problem
+%D because \TEX\ does not load a font twice. We could have
+%D combined some arguments, like the height, vertical offset
+%D and the number of lines, but the current implementation
+%D proved to be the most flexible. One should be aware of the
+%D fact that the offsets depend on the design of the glyphs
+%D used.
+
+\let\DroppedIndent\!!zeropoint \def\DroppedLines{0}
+
+\def\DroppedString{ABCDEFGHIJKLMNOPQRSTUVWXYZ}
+
+\let\globaldropcaps\global % will be an option, but on by default
+
+\unexpanded\def\localdropcaps{\let\globaldropcaps\relax}
+
+\chardef\DroppedStatus = 0 % 0=done 1=starting 2=doing 3=error
+\chardef\DropMode = 0 % 1 == marginhang
+
+\ifx\keeplinestogether\undefined
+ \let\keeplinestogether\gobbleoneargument
+\fi
+
+\unexpanded\def\DroppedCaps#1#2#3#4#5#6#7% does not yet handle accented chars
+ {\defconvertedargument\asciia{#7}%
+ \defconvertedcommand \asciib{\DroppedString}%
+ \doifelseinstring\asciia\asciib
+ {\noindentation
+ \dontleavehmode
+ \checkindentation % redo this one
+ %\ifhmode\hskip-\parindent\fi % sensitive for context mechanism
+ \keeplinestogether{#6}%
+ \setbox0\hbox{\definedfont[#2 at #3]#1{#7}\hskip#4}%
+ \ifdim\dp0>\strutdp % one of those Q's , will be option
+ \setbox2\hbox{\raise\dp0\hbox{\lower\strutdp\copy0}}%
+ \ht2\ht0
+ \dp0\strutdp
+ \setbox0\box2
+ \fi
+ \setbox0\hbox
+ {\ifnum\DropMode=\plusone
+ \hskip-\wd0\wd0\zeropoint
+ \fi
+ \lower#5\box0}%
+ \ht0\strutht
+ \dp0\strutdp
+ \ifnum\DropMode=\plusone
+ \globaldropcaps\let\DroppedIndent\!!zeropoint
+ \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
+ \globaldropcaps\chardef\DroppedStatus\plusthree
+ \else
+ \globaldropcaps\edef\DroppedIndent{\the\wd0}%
+ \globaldropcaps\edef\DroppedLines {\number#6}%
+ \globaldropcaps\chardef\DroppedStatus\plustwo
+ \globaldropcaps\hangindent\DroppedIndent
+ \globaldropcaps\hangafter-\DroppedLines
+% \noindent
+ \noindentation
+ \checkindentation % redo this one
+ \hskip-\DroppedIndent
+ \fi
+ \vbox{\forgetall\box0}%
+ \nobreak
+ \let\next\ignorespaces} % Could be a one character word !
+ {\globaldropcaps\let\DroppedIndent\!!zeropoint
+ \globaldropcaps\edef\DroppedLines{\number\maxdimen}%
+ \globaldropcaps\chardef\DroppedStatus\plusthree
+ \def\next{#7}}%
+ \let\globaldropcaps\global
+ \next}
+
+%D Before we go to the next topic, we summarize this command:
+%D
+%D \starttyping
+%D \DroppedCaps
+%D {command} {font}
+%D {height} {hoffset} {voffset} {lines}
+%D \stoptyping
+%D
+%D Sometimes you need to make sure that the global settings are
+%D kept local, as in:
+%D
+% %D \startbuffer
+% %D \defineparagraphs[SomePar][n=2,rule=on]
+% %D \setupparagraphs [SomePar][1][width=.5\textwidth]
+% %D \setupparagraphs [SomePar][2][width=.5\textwidth]
+%D \startbuffer
+%D \defineparagraphs[SomePar][n=2,rule=on]
+%D \setupparagraphs [SomePar][1][width=.5\textwidth]
+%D \setupparagraphs [SomePar][2][width=.5\textwidth]
+%D
+%D \startSomePar
+%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
+%D to explicitly keep the hanging indentation local, like it or
+%D not.
+%D \SomePar
+%D \localdropcaps\NiceDroppedCaps{}{cmr12}{0pt}{2}Here we need
+%D to explicitly keep the hanging indentation local, like it or
+%D not.
+%D \stopSomePar
+%D \stopbuffer
+%D
+%D \typebuffer \getbuffer
+
+%D \macros
+%D {AutoDroppedCaps, CheckDroppedCaps}
+%D
+%D {\em To be documented.}
+
+% example usage
+%
+% \def\bpar{\ifvmode\CheckDroppedCaps\fi}
+% \def\epar{\ifhmode\par\fi\CheckDroppedCaps}
+
+\newcount\lastprevgraf
+\newcount\droppedlines
+
+\unexpanded\def\CheckDroppedCaps
+ {\global\lastprevgraf\prevgraf}
+
+\unexpanded\def\AutoDroppedCaps % will be proper core stuff since it
+ {\globaldropcaps\chardef\DroppedStatus\plusone
+ \global\lastprevgraf\zerocount
+ \global\droppedlines\zerocount
+ \EveryPar{\doAutoDroppedCaps}}
+
+\let\AutoDroppedNext\relax
+
+\ifx\AutoDroppedCapsCommand\undefined
+ \unexpanded\def\AutoDroppedCapsCommand{\NiceDroppedCaps{}{SerifBold}{.125em}{3}}
+\fi
+
+\unexpanded\def\doAutoDroppedCaps
+ {\ifcase\DroppedStatus % done
+ \let\next\relax
+ \or % starting
+ % \ifnum\lastprevgraf>0 % tricky, probably a wrong par
+ % \globaldropcaps\chardef\DroppedStatus=3 % and inhibits dropped
+ % \let\next\relax % caps after titles and more than once
+ % \else % so let's nill this rubishly code fragment
+ \let\next\AutoDroppedCapsCommand
+ % \fi % and hope for the best
+ \or % doing
+ \global\advance\droppedlines \lastprevgraf
+ \ifnum\droppedlines=\zerocount
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \else\ifnum\droppedlines>\zerocount
+ \ifnum\droppedlines<\DroppedLines\relax
+ \globaldropcaps\hangindent\DroppedIndent
+ \globaldropcaps\hangafter-\DroppedLines
+ \globaldropcaps\advance\hangafter \droppedlines
+ \hskip-\parindent % brrr
+ \let\next\AutoDroppedNext
+ \else
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi
+ \else
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi\fi
+ \or % error
+ \globaldropcaps\chardef\DroppedStatus\zerocount
+ \let\next\relax
+ \fi
+ \next}
+
+%D \macros
+%D {LineDroppedCaps, NiceDroppedCaps}
+%D
+%D To save definitions, we also provide:
+%D
+%D \starttyping
+%D \LineDroppedCaps {command} {font} {hoffset} {lines}
+%D \NiceDroppedCaps {command} {font} {hoffset} {lines}
+%D \stoptyping
+%D
+%D The first command scales the font to the exact height, while
+%D the second command scales the font to a nice 2.5 times the
+%D line height, a value that gives a pleasant grayness.
+
+\unexpanded\def\DoLineDroppedCaps#1#2#3#4#5% compensation command font offset lines
+ {\scratchcounter#5%
+ \advance\scratchcounter \minusone
+ \scratchdimen\scratchcounter\baselineskip
+ \advance\scratchdimen #1%
+ \NormalizeFontHeight\DummyFont{W}\scratchdimen{#3}%
+ \DroppedCaps{#2}{#3}\TheNormalizedFontSize{#4}
+ {\scratchcounter\baselineskip}{#5}}
+
+\unexpanded\def\LineDroppedCaps% command font offset lines
+ {\DoLineDroppedCaps{\strutht}}
+
+\unexpanded\def\NiceDroppedCaps% command font offset lines
+ {\DoLineDroppedCaps{.5\baselineskip}}
+
+%D \macros
+%D {TreatFirstLine}
+%D
+%D \startbuffer
+%D \TreatFirstLine {\sc} {} {} {}
+%D Instead of limiting its action to one token, the next macro
+%D treats the whole first line. This paragraph was typeset by
+%D saying:
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D \startbuffer
+%D \TreatFirstLine {\startcolor[red]\bf} {\stopcolor} {} {}
+%D The combined color and font effect is also possible,
+%D although one must be careful in using macros that accumulate
+%D grouping, but the commands used here are pretty save in that
+%D respect.
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D Before we explain the third and fourth argument, we show the
+%D implementation. Those who know a bit about the way \TEX\
+%D treats tokens, will probably see in one glance that this
+%D alternative works all right for most text||only situations
+%D in which there is enough text available for the first line,
+%D but that more complicated things will blow. One has to live
+%D with that. A workaround is rather trivial but obscures the
+%D principles used.
+
+\unexpanded\def\TreatFirstLine#1#2#3#4% before, after, first, next
+ {\leavevmode
+ \bgroup
+ \forgetall
+ \bgroup
+ #1%
+ \setbox0\emptybox
+ \setbox2\emptybox
+ \def\grabfirstline##1 %
+ {\setbox2\hbox
+ {\ifvoid0
+ {#3{\ignorespaces##1}}%
+ \else
+ \unhcopy0\ {#4{##1}}%
+ \fi}%
+ \ifdim\wd2=\zeropoint
+ \setbox0\emptybox
+ \setbox2\emptybox
+ \@EA\grabfirstline
+ \else\ifdim\wd2>\hsize
+ \hbox to \hsize{\strut\unhbox0}#2\egroup
+ \break##1\
+ \egroup
+ \else
+ \setbox0\box2
+ \@EAEAEA\grabfirstline
+ \fi\fi}%
+ \grabfirstline}
+
+%D \startbuffer
+%D \gdef\FunnyCommand
+%D {\getrandomfloat\FunnyR{0}{1}%
+%D \getrandomfloat\FunnyG{0}{1}%
+%D \getrandomfloat\FunnyB{0}{1}%
+%D \definecolor[FunnyColor][r=\FunnyR,g=\FunnyG,b=\FunnyB]%
+%D \color[FunnyColor]}
+%D
+%D %\TreatFirstLine {\bf} {} {\FunnyCommand} {\FunnyCommand}
+%D The third and fourth argument can be used to gain special
+%D effects on the individual words. Of course one needs ...
+%D \stopbuffer
+%D
+%D \getbuffer
+%D to know a bit more about the macro package used to get real
+%D nice effects, but this example probably demonstrates the
+%D principles well.
+%D
+%D \typebuffer
+%D
+%D Like in dropped caps case, one can hide such treatments in a
+%D macro, like:
+%D
+%D \starttyping
+%D \def\MyTreatFirstLine%
+%D {\TreatFirstLine{\bf}{}{\FunnyCommand}{\FunnyCommand}}
+%D \stoptyping
+
+%D \macros
+%D {reshapebox}
+%D
+%D \startbuffer
+%D \beginofshapebox
+%D When using \CONTEXT, one can also apply this funny command
+%D to whole lines by using the reshape mechanism. Describing
+%D this interesting mechanism falls outside the scope of this
+%D module, so we only show the trick. This is an example of
+%D low level \CONTEXT\ functionality: it's all there, and it's
+%D stable, but not entirely meant for novice users.
+%D \endofshapebox
+%D
+%D \reshapebox{\FunnyCommand{\box\shapebox}} \flushshapebox
+%D \stopbuffer
+%D
+%D \getbuffer
+%D
+%D \typebuffer
+%D
+%D This mechanism permits hyphenation and therefore gives
+%D better results than the previously discussed macro
+%D \type{\TreatFirstLine}.
+
+%D \macros
+%D {TreatFirstCharacter}
+%D
+%D \startbuffer
+%D \TreatFirstCharacter{\bf\color[green]} Just to be
+%D \stopbuffer
+%D
+%D \getbuffer complete we also offer a very simple one
+%D character alternative, that is not that hard to understand:
+
+\unexpanded\def\TreatFirstCharacter#1#2% command, character
+ {{#1{#2}}}
+
+%D A previous paragraph started with:
+%D
+%D \typebuffer
+
+%D \macros
+%D {StackCharacters}
+%D
+%D The next hack deals with vertical stacking.
+
+\unexpanded\def\StackCharacters#1#2#3#4% sequence vsize vskip command
+ {\vbox #2
+ {\forgetall
+ \baselineskip\zeropoint
+ \def\StackCharacter##1{#4{##1}\cr\noalign{#3}}%
+ \halign
+ {\hss##\hss&##\cr
+ \handletokens#1\with\StackCharacter\cr}}}
+
+%D \startbuffer
+%D \StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}
+%D \stopbuffer
+%D
+%D Such a stack looks like:
+%D
+%D \startlinecorrection
+%D \hbox to \hsize
+%D {$\hss\bfd
+%D \vcenter{\StackCharacters{TEX} {}{\vskip.2ex}{\FunnyCommand}}%
+%D \hss
+%D \vcenter{\StackCharacters{CON} {}{\vskip.2ex}{\FunnyCommand}}
+%D \hss
+%D \vcenter{\StackCharacters{TEXT} {}{\vskip.2ex}{\FunnyCommand}}
+%D \hss
+%D \vcenter{\StackCharacters{CONTEXT}{}{\vskip.2ex}{\FunnyCommand}}
+%D \hss$}
+%D \stoplinecorrection
+%D
+%D and is typeset by saying:
+%D
+%D \typebuffer
+%D
+%D An alternative would have been
+%D
+%D \starttyping
+%D \StackCharacters {CONTEXT} {to 5cm} {\vfill} {\FunnyCommand}
+%D \stoptyping
+
+%D \macros
+%D {processtokens}
+%D
+%D At a lower level horizontal and vertical manipulations are
+%D already supported by:
+%D
+%D \starttyping
+%D \processtokens {begin} {between} {end} {space} {text}
+%D \stoptyping
+%D
+%D \startbuffer[a]
+%D \processtokens
+%D {\hbox to .5\hsize\bgroup} {\hfill}
+%D {\egroup} {\space} {LET'S HAVE}
+%D \stopbuffer
+%D
+%D \startbuffer[b]
+%D \processtokens
+%D {\vbox\bgroup\raggedcenter\hsize1em}
+%D {\vskip.25ex} {\egroup} {\strut} {FUN}
+%D \stopbuffer
+%D
+%D This macro is able to typeset:
+%D
+%D \leavevmode\hbox to \hsize
+%D {$\hfil\hfil
+%D \vcenter{\bf\getbuffer[a]}%
+%D \hfil
+%D \vcenter{\bfd\getbuffer[b]}%
+%D \hfil\hfil$}
+%D
+%D which was specified as:
+%D
+%D \typebuffer[a]
+%D \typebuffer[b]
+
+%D \macros
+%D {NormalizeFontHeight, NormalizeFontWidth,
+%D TheNormalizedFontSize}
+%D
+%D Next we introduce some font manipulation macros. When we
+%D want to typeset some text spread in a well defined area, it
+%D can be considered bad practice to manipulate character and
+%D word spacing. In such situations the next few macros can be
+%D of help:
+%D
+%D \starttyping
+%D \NormalizeFontHeight \name {sample text} {height} {font}
+%D \NormalizeFontWidth \name {sample text} {width} {font}
+%D \stoptyping
+%D
+%D These are implemented using an auxilliary macro:
+
+\unexpanded\def\NormalizeFontHeight{\NormalizeFontSize\ht}
+\unexpanded\def\NormalizeFontWidth {\NormalizeFontSize\wd}
+
+\unexpanded\def\NormalizeFontSize#1#2#3#4#5%
+ {\bgroup
+ \dimen0=#4% #4 can be \ht0 or so
+ \setbox0\hbox{\definedfont[#5 at 5pt]#3}% 10pt
+ \ifdim\wd0>\zeropoint
+ \dimen2=#10 % #1 is \wd or \ht
+ \dimen4=\maxdimen % 10000pt
+ \divide\dimen4 \dimen2
+ \divide\dimen0 1638 % 1000
+ \dimen0=\number\dimen4\dimen0
+ \divide \dimen0 \plustwo % ...
+ \xdef\TheNormalizedFontSize{\the\dimen0}%
+ \else
+ \dimen0\bodyfontsize
+ \fi
+ \normalexpanded{\egroup\def\noexpand#2{\definedfont[#5 at \the\dimen0]}}}
+
+%D Afterwards, we have access to the calculated size by:
+
+\let\TheNormalizedFontSize\!!zeropoint
+
+%D Extra:
+
+\unexpanded\def\WidthSpanningText#1#2#3% text width font
+ {\hbox{\NormalizeFontWidth\temp{#1}{#2}{#3}\temp\the\everydefinedfont#1}}
+
+%D Consider for instance:
+%D
+%D \startbuffer
+%D \NormalizeFontHeight \tmp {X} {2\baselineskip} {cmr10}
+%D
+%D {\tmp To Be Or Not To Be}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D This shows up as (we also show the baselines):
+%D
+%D {\showbaselines\getbuffer}
+%D
+%D The horizontal counterpart is:
+%D
+%D \startbuffer
+%D \NormalizeFontWidth \tmp {This Line Fits} {\hsize} {cmr10}
+%D
+%D \hbox{\tmp This Line Fits}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D The calculated font scale is avaliable in the macro
+%D \type{\NormalizedFontSize}.
+%D
+%D \startlinecorrection
+%D \ruledhbox{\getbuffer}
+%D \stoplinecorrection
+%D
+%D One can of course combine these macros with the ones
+%D described earlier, like in:
+%D
+%D \starttyping
+%D \NormalizeFontHeight {text} \DroppedFont {2\baselineskip} {cmbx12}
+%D
+%D \def\NicelyDroppedCaps
+%D {\DroppedCaps
+%D {\color[green]}
+%D {\DroppedFont}
+%D {2pt}
+%D {\baselineskip}
+%D {2}}
+%D \stoptyping
+%D
+%D It's up to the reader to test this one.
+
+\unexpanded\def\FirstNCharacters#1#2% \FirstNCharacters{3}{fr{\"o}beln}
+ {\bgroup
+ \scratchcounter\zerocount
+ \def\docommand##1%
+ {\ifnum\scratchcounter=#1\else
+ ##1\relax % catches ##1 = \"e and alike
+ \advance\scratchcounter\plusone
+ \fi}
+ \handletokens#2\with\docommand
+ \egroup}
+
+%D \macros
+%D {FittingText}
+%D
+%D First used in Pascal (demo-bbv):
+%D
+%D \startbuffer
+%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
+%D {\veryraggedright
+%D \hangindent1em\hangafter1\relax
+%D \begstrut \dorecurse{8}{Bram Marta }\unskip \endstrut}}
+%D
+%D \ruledvbox{\FittingText{3cm}{1cm}{Serif}{24pt}{1pt}{1}
+%D {\raggedleft\begstrut Bram\\Marta \unskip\endstrut}}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startlinecorrection
+%D \getbuffer
+%D \stoplinecorrection
+
+% #1 width #2 height #3 font #4 size #5 step #6 interlinie #7 text
+
+\unexpanded\def\FittingText#1#2#3#4#5#6#7%
+ {\bgroup
+ \forgetall
+ \dontcomplain
+ \setuptolerance[\v!verytolerant]% == \tolerance4500
+ \hsize#1%
+ \def\\{\softbreak}%
+ \!!heighta#4%
+ \!!heightb#2%
+ \doloop
+ {\ifdim\!!heighta>\onepoint
+ \expanded{\definefont[\s!dummy][#3 at \the\!!heighta][\c!interlinespace=#6]}%
+ \getvalue\s!dummy
+ \setbox\scratchbox\vbox{#7\endgraf}%
+ \ifdim\ht\scratchbox>\!!heightb
+ \advance\!!heighta-#5%
+ \else
+ \beginshapebox
+ \unvcopy\scratchbox
+ \endshapebox
+ \global\dimen1\hsize
+ \reshapebox
+ {\setbox\shapebox\hbox{\unhbox\shapebox}%
+ \ifdim\wd\shapebox>\dimen1
+ \global\dimen1\wd\shapebox
+ \fi}%
+ \ifdim\dimen1>\hsize
+ \advance\!!heighta-#5%
+ \else
+ \exitloop
+ \fi
+ \fi
+ \else
+ \exitloop
+ \fi}%
+ %\writestatus{\strippedcsname\FittingText}{height: \the\!!heighta}%
+ \unvbox\scratchbox
+ \egroup}
+
+% \font width gap font spec text
+
+\unexpanded\def\NormalizeFontWidthSpread#1#2#3#4#5#6%
+ {\global\setfalse\NFSpread
+ \scratchdimen#3%
+ \scratchdimen-.5\scratchdimen
+ \advance\scratchdimen#2\relax
+ \NormalizeFontWidth
+ #1%
+ {\def\+{\global\settrue\NFSpread\gobbleuntil\relax}%
+ \def\\{\gobbleuntil\relax}% newline
+ \setupspacing
+ #6\relax}%
+ {\scratchdimen}%
+ {#4}%
+ \ifconditional\NFSpread
+ % de gap valt in de binding
+ \else
+ \definefont[\strippedcsname#1][#4 #5]%
+ \fi}
+
+\unexpanded\def\SpreadGapText#1#2%
+ {{\def\+{\kern#1}#2}}
+
+\unexpanded\def\GapText#1#2#3#4#5% width distance font spec title
+ {\bgroup
+ \NormalizeFontWidthSpread\DummyFont{#1}{#2}{#3}{#4}{#5}%
+ \DummyFont\setupspacing\SpreadGapText{#2}{#5}\endgraf
+ \egroup}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-oldnum.mkiv b/tex/context/modules/mkiv/m-oldnum.mkiv
new file mode 100644
index 000000000..382c56eb6
--- /dev/null
+++ b/tex/context/modules/mkiv/m-oldnum.mkiv
@@ -0,0 +1,416 @@
+%D \module
+%D [ file=m-oldnum, % was: supp-num
+%D version=1998.05.15,
+%D title=\CONTEXT\ Support Macros,
+%D subtitle=Numbers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% See end for transition to mkiv.
+
+\writestatus{loading}{ConTeXt Support Macros / Numbers}
+
+\unprotect
+
+%D \macros
+%D {digits, setdigitmode, setdigitsign}
+%D
+%D Depending on the digit mode the command \type {\digits}
+%D normalizes number patterns depending on the language set.
+%D
+%D \starttyping
+%D This will never be a \digits{1.000.000} seller.
+%D \stoptyping
+%D
+%D or
+%D
+%D \starttyping
+%D I will never grow longer than \digits 1.86 \Meter.
+%D \stoptyping
+%D
+%D The different modes are shown in:
+%D
+%D \startbuffer
+%D \setdigitmode 1 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 2 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 3 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 4 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 5 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \setdigitmode 6 \digits 12.345,90 \digits 12.345.000 \digits 1,23
+%D \stopbuffer
+%D
+%D \typebuffer
+%
+% This is typset as:
+%
+% \startlines
+% \getbuffer
+% \stoplines
+%D
+%D The sign can be typeset as is or within the space of a
+%D digit.
+%D
+%D \startbuffer
+%D \setdigitsign 0 \digits +12.345,90
+%D \setdigitsign 1 \digits +12.345,90
+%D \setdigitsign 2 \digits +12.345,90
+%D \setdigitsign 3 \digits +12.345,90
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+% This is typset as:
+%
+% \startlines
+% \getbuffer
+% \stoplines
+
+\chardef\digitoutputmode=1 % 0..6
+\chardef\digitsignmode =0 % 0..3
+
+\unexpanded\def\setdigitmode{\chardef\digitoutputmode}
+\unexpanded\def\setdigitsign{\chardef\digitsignmode}
+
+%D The digit modes are:
+%D
+%D \startitemize[packed]
+%D \item periods \& comma
+%D \item commas \& period
+%D \item thinmuskips \& comma
+%D \item thinmuskips \& period
+%D \item thickmuskips \& comma
+%D \item thickmuskips \& period
+%D \stopitemize
+
+\let\collecteddigits \empty \chardef\digitinputmode =1
+\let\saveddigits \empty \chardef\skipdigit =0
+\let\savedpowerdigits\empty \chardef\powerdigits =0
+
+%D The first stage of the \type {\digit} macro takes care of
+%D the grouped call, the other branch handles the fuzzy
+%D delimited calls.
+
+\ifdefined\mbox \else \let\mbox\hbox \fi
+
+\unexpanded\def\digits
+ {\bgroup
+ \let~@%
+ \doifelsenextbgroup\dodigits{\doifelsenextchar\normalmathshift\domathdigits\grabdigit}}
+
+\def\dodigits#1%
+ {\grabdigit#1\relax}
+
+\def\domathdigits$#1$%
+ {\mbox{\grabdigit#1\relax}} % adding $ $ goes wrong in tabulate
+
+\def\grabdigit
+ {\futurelet\next\scandigit}
+
+%D Watch the test for \type {\nextobeyedline}, because the
+%D endofline token can be \type {\def'd}, not \type {\let}'d,
+%D we need to do an indirect test (see \type {verb-ini.tex})
+%D for details. (This probably needs an update.)
+
+\ifx\normalmathshift\undefined \let\normalmathshift=$ \fi
+
+\unexpanded\def\scandigit
+ {\ifx\next\blankspace
+ \let\next\handledigits
+ \else\ifx\next\nextobeyedline % the indirect one
+ \let\next\handledigits
+ \else\ifx\next\bgroup
+ \let\next\handledigits
+ \else\ifx\next\egroup
+ \let\next\handledigits
+ \else\ifx\next\normalmathshift
+ \let\next\handledigits
+ \else
+ \let\next\collectdigit
+ \fi\fi\fi\fi\fi
+ \next}
+
+%D We store the power||of||ten (to be signaled by \type {^},
+%D \type {e} or~\type {E}) in a seperate macro so that we can
+%D typeset it in superscript. The space placeholders are
+%D replaced by a \type {@}.
+
+\unexpanded\def\savedigit#1#2%
+ {\edef#1{#1\saveddigits#2}\let\saveddigits\empty}
+
+\unexpanded\def\collectdigit#1%
+ {\ifx#1~%
+ \savedigit\collecteddigits @%
+ \else\if#1_% tricky as can be several catcodes ... will become lua code anyway
+ \savedigit\collecteddigits @%
+ \else\if\noexpand#1\relax
+ \let\grabdigit\handledigits
+ \else\ifcase\powerdigits
+ \if#1E%
+ \chardef\powerdigits\plusone
+ \else\if#1e%
+ \chardef\powerdigits\plusone
+ \else\if#1^%
+ \chardef\powerdigits\plusone
+ \else
+ \savedigit\collecteddigits#1%
+ %\doifelsenumber{#1}
+ % {\savedigit\collecteddigits#1}
+ % {\def\saveddigits{#1}}%
+ \fi\fi\fi
+ \else
+ \savedigit\savedpowerdigits#1%
+ %\doifelsenumber{#1}
+ % {\savedigit\savedpowerdigits#1}
+ % {\def\saveddigits{#1}}%
+ \fi\fi\fi\fi
+ \grabdigit}
+
+\let\handlemathdigits\firstofoneargument
+\let\handletextdigits\mathematics
+
+\unexpanded\def\handledigits
+ {%\ifcase\powerdigits
+ % \edef\collecteddigits{\collecteddigits\saveddigits}%
+ %\else
+ % \edef\savedpowerdigits{\savedpowerdigits\saveddigits}%
+ %\fi
+ \ifmmode
+ \handlemathdigits{\dohandledigits}%
+ \else
+ \dontleavehmode\hbox{\handletextdigits{\dohandledigits}}%
+ \fi
+ \egroup}
+
+%D Although we could do with one pass, a second pass for
+%D handling the stored sequence is more readable.
+
+\ifnum\texengine=\luatexengine
+
+ \def\dohandledigits
+ {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+ \chardef\mathaxisfontid\zerocount
+
+\else
+
+ \def\dohandledigits
+ {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded
+ \expandafter\handletokens\collecteddigits\with\scandigits
+ \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
+
+ \chardef\mathaxisfontid\plustwo
+
+\fi
+
+\def\doscandigit#1%
+ {\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup
+ \mathematics % brr, needed because of stored punctuation
+ {\ifnum\digitinputmode=#1\relax
+ \ifcase\digitoutputmode
+ \or .%
+ \or ,%
+ \or \mskip\thinmuskip
+ \or \mskip\thinmuskip
+ \or \mskip\thickmuskip
+ \or \mskip\thickmuskip
+ \fi
+ \else
+ \ifodd\digitoutputmode,\else.\fi
+ \fi}%
+ \egroup}
+
+%D The signs can be made smaller and sqeezed into the width
+%D of a digit. Watch the \type {\mathaxisheight} trickery (this
+%D font related register stored the math axis).
+
+% 0,=
+% 0,== second = results in delta(00,=)
+% 0,- is invalid, should be =
+% 0,-- is invalid, should be ==
+
+\unexpanded\def\digitzeroamount
+ {\digitsgn\zeroamount
+ \def\digitzeroamount
+ {\hphantom
+ {00\setbox\scratchbox\hbox{$\zeroamount$}%
+ \hskip-\wd\scratchbox}%
+ \let\digitzeroamount\empty}}
+
+\unexpanded\def\scandigits#1%
+ {\if#1.\digitsep1\else
+ \if#1,\digitsep2\else
+ \if#1@\digitnop \else
+ \if#1_\digitnop \else
+ \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else
+ \if#1-\ifcase\skipdigit\digitsgn-\else
+ \box\digitsepbox\digitzeroamount \fi\chardef\skipdigit0\else
+ \if#1+\digitsgn+\chardef\skipdigit0\else
+ \if#1=\box\digitsepbox\digitzeroamount \chardef\skipdigit0\else
+ \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else
+ \if#1p\digitsgn\positive\chardef\skipdigit0\else
+ \if#1m\digitsgn\negative\chardef\skipdigit0\else
+ \if#1n\digitsgn\negative\chardef\skipdigit0\else
+ \box\digitsepbox #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+\newbox\digitsepbox \chardef\autodigitmode=1
+
+\unexpanded\def\digitsep#1%
+ {\ifcase\autodigitmode
+ \doscandigit#1%
+ \else
+ \setbox\digitsepbox\hbox{\doscandigit#1}%
+ \fi
+ \chardef\skipdigit0\relax}
+
+% strange, does not work
+%
+% \def\digitnop
+% {\hphantom{\box\digitsepbox}%
+% \hphantom{0}\chardef\skipdigit1\relax}
+%
+% while this works
+
+\unexpanded\def\digitnop
+ {\hbox{\hphantom{\box\digitsepbox}}%
+ \hphantom{0}\chardef\skipdigit1\relax}
+
+% but this doesn't
+%
+% \def\digitnop
+% {\hphantom{\box\digitsepbox0}%
+% \chardef\skipdigit1\relax}
+
+\unexpanded\def\digitsgn#1%
+ {\ifcase\digitsignmode#1\else
+ \hbox
+ {\setbox\scratchbox\hbox{0}%
+ \scratchdimen\mathaxisheight\textfont\mathaxisfontid
+ \def\digitsgn##1##2%
+ {\advance\scratchdimen-\mathaxisheight##1\mathaxisfontid
+ \raise\scratchdimen
+ \hbox to \wd\scratchbox{\hss$##2#1$\hss}}%
+ \ifcase\digitsignmode\or
+ \digitsgn\textfont \textstyle \or
+ \digitsgn\scriptfont \scriptstyle \or
+ \digitsgn\scriptscriptfont\scriptscriptstyle\fi}%
+ \fi}
+
+\ifx\undefined\zeroamount \def\zeroamount{-} \fi
+\ifx\undefined\positive \def\positive {+} \fi
+\ifx\undefined\negative \def\negative {-} \fi
+
+%D The digit parser handles a bunch of special characters as
+%D well as different formats. We strongly suggest you to use
+%D the grouped call.
+%D
+%D \starttabulate[|l|l|l|]
+%D \NC \type{.} \NC , . \NC comma or period \NC \NR
+%D \NC \type{,} \NC , . \NC comma or period \NC \NR
+%D \NC \type{@} \NC \NC invisible space \NC \NR
+%D \NC \type{_} \NC \NC invisible space \NC \NR
+%D \NC \type{/} \NC \NC invisible sign \NC \NR
+%D \NC \type{-} \NC $-$ \NC minus sign \NC \NR
+%D \NC \type{+} \NC $+$ \NC plus sign \NC \NR
+%D \NC \type{s} \NC \NC invisible high sign \NC \NR
+%D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR
+%D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR
+%D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR
+%D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR
+%D \stoptabulate
+%D
+%D These triggers are used in the following examples.
+%D
+%D \startbuffer
+%D \digits 12
+%D \digits{~~~.~~~.~~~.68.712,34}
+%D \digits ~~~.~~~.~~~.68.712,34
+%D \digits ___.___.111.68.712,34
+%D \digits 111.111.111.68.712,34
+%D \digits 12.345,90
+%D \digits 12.345.000
+%D \digits 12,34
+%D \digits{392.857.230.68.712,34}
+%D {\digits1234}
+%D \digits{1234}
+%D \digits 1234\relax
+%D $\digits 123.222,00$
+%D \digits 123.222,00
+%D \digits 123.222,==
+%D \digits 123.222,00^10
+%D \digits 123.222,00e10
+%D \digits /123.222,00e-12
+%D \digits -123.222,00e-12
+%D \digits +123.222,00e-12
+%D \digits n123.222,00e-12
+%D \digits s123.222,00e-12
+%D \digits p123.222,00e-12
+%D \stopbuffer
+%D
+%D \typebuffer
+%
+% \startlines
+% \getbuffer
+% \stoplines
+
+%D \macros
+%D {Digits}
+%D
+%D We also permit:
+
+\let\Digits\digits
+
+%D These macros are complicated by the fact that we also
+%D have to support cases like:
+%D
+%D \starttyping
+%D {\digits1234}
+%D \digits{1234}
+%D \digits 1234\whatever
+%D $\digits 123.222,00$
+%D \digits 123.222,00.
+%D \stoptyping
+%D
+%D The latter case shows us that trailing non digits are to
+%D be passed untreated.
+%D
+%D Another interesting case is:
+%D
+%D \starttyping
+%D \digits 123.222,00^10
+%D \stoptyping
+%D
+%D The separator is defined as:
+
+% \def\digitpowerseparator%
+% {\cdot10} % {\times10}
+
+\def\digitpowerseparator
+ {\ifx\collecteddigits\empty\else\cdot\fi10}
+
+%D \macros
+%D {digittemplate}
+%D
+%D Users can specify the way they enter those digits by saying
+%D something like:
+%D
+%D \starttyping
+%D \digittemplate 12.000.000,00 % \digittemplate .,
+%D \stoptyping
+
+\unexpanded\def\digittemplate #1 %
+ {\chardef\digitinputmode\zerocount
+ \handletokens#1\with\scandigittemplate}
+
+\unexpanded\def\scandigittemplate#1%
+ {\if #1.\ifcase\digitinputmode\chardef\digitinputmode\plusone \fi% period
+ \else\if#1,\ifcase\digitinputmode\chardef\digitinputmode\plustwo \fi% comma
+ \fi\fi}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-pictex.mkiv b/tex/context/modules/mkiv/m-pictex.mkiv
new file mode 100644
index 000000000..73aad3f57
--- /dev/null
+++ b/tex/context/modules/mkiv/m-pictex.mkiv
@@ -0,0 +1,46 @@
+%D \module
+%D [ file=m-pictex,
+%D version=1997.01.15,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PICTEX\ Loading Macros,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Just in case someone still uses \PICTEX:
+
+\ifdefined\beginpicture \else
+
+ \ifdefined\grid \else
+ \let\normalgrid\grid
+ \fi
+
+ \ifdefined\axis \else
+ \let\normalaxis\axis
+ \fi
+
+ \ifdefined\fiverm \else
+ \font\fiverm=cmr5
+ \fi
+
+ \input prepictex.tex \relax
+ \input pictex.tex \relax
+ \input postpictex.tex \relax
+
+ \ifdefined\normalgrid
+ \let\pictexgrid\grid
+ \let\grid\normalgrid
+ \fi
+
+ \ifdefined\normalaxis
+ \let\pictexaxis\axis
+ \let\axis\normalaxis
+ \fi
+
+\fi
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-pipemode.mkiv b/tex/context/modules/mkiv/m-pipemode.mkiv
new file mode 100644
index 000000000..e96394c43
--- /dev/null
+++ b/tex/context/modules/mkiv/m-pipemode.mkiv
@@ -0,0 +1,7 @@
+% For Mojca: context --global m-pipemode.mkiv
+
+\disabledirectives[system.errorcontext]
+
+\starttext
+
+\let\stoptext\relax
diff --git a/tex/context/modules/mkiv/m-pstricks.lua b/tex/context/modules/mkiv/m-pstricks.lua
new file mode 100644
index 000000000..b151e313a
--- /dev/null
+++ b/tex/context/modules/mkiv/m-pstricks.lua
@@ -0,0 +1,74 @@
+if not modules then modules = { } end modules ['m-pstricks'] = {
+ version = 1.001,
+ comment = "companion to m-pstricks.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- The following will be done when I need ps tricks figures
+-- in large quantities:
+--
+-- + hash graphics and only process them once
+-- + save md5 checksums in tuc file
+--
+-- It's no big deal but has a low priority.
+
+local format, lower, concat, gmatch = string.format, string.lower, table.concat, string.gmatch
+local variables = interfaces.variables
+
+moduledata.pstricks = moduledata.pstricks or { }
+
+local report_pstricks = logs.reporter("pstricks")
+
+local template = [[
+\starttext
+ \pushcatcodetable
+ \setcatcodetable\texcatcodes
+ \usemodule[pstric]
+ %s
+ \popcatcodetable
+ \startTEXpage
+ \hbox\bgroup
+ \ignorespaces
+ %s
+ \removeunwantedspaces
+ \egroup
+ \obeydepth %% temp hack as we need to figure this out
+ \stopTEXpage
+\stoptext
+]]
+
+local loaded = { }
+local graphics = 0
+
+function moduledata.pstricks.usemodule(names)
+ for name in gmatch(names,"([^%s,]+)") do
+ loaded[#loaded+1] = format([[\readfile{%s}{}{}]],name)
+ end
+end
+
+function moduledata.pstricks.process(n)
+ graphics = graphics + 1
+ local name = format("%s-pstricks-%04i",tex.jobname,graphics)
+ local data = buffers.collectcontent("def-"..n)
+ local tmpfile = name .. ".tmp"
+ local epsfile = name .. ".ps"
+ local pdffile = name .. ".pdf"
+ local loaded = concat(loaded,"\n")
+ os.remove(epsfile)
+ os.remove(pdffile)
+ io.savedata(tmpfile,format(template,loaded,data))
+ os.execute(format("mtxrun --script texexec %s --once --dvips",tmpfile))
+ if lfs.isfile(epsfile) then
+ os.execute(format("ps2pdf %s %s",epsfile,pdffile))
+ -- todo: direct call but not now
+ if lfs.isfile(pdffile) then
+ context.externalfigure( { pdffile }, { object = variables.no } )
+ else
+ report_pstricks("run failed, no pdf file")
+ end
+ else
+ report_pstricks("run failed, no ps file")
+ end
+end
diff --git a/tex/context/modules/mkiv/m-pstricks.mkiv b/tex/context/modules/mkiv/m-pstricks.mkiv
new file mode 100644
index 000000000..421607aaf
--- /dev/null
+++ b/tex/context/modules/mkiv/m-pstricks.mkiv
@@ -0,0 +1,65 @@
+%D \module
+%D [ file=m-pstricks,
+%D version=2010.03.14,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PSTRICKS\ Connections,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\registerctxluafile{m-pstricks}{}
+
+\unprotect
+
+% best we can make a special colors module
+%
+% \let\@unused\plussixteen
+% \let\alloc@ \gobblefivearguments
+%
+% \def\loadpstrickscolors#1%
+% {\pushmacro\dodefinecolor
+% \pushmacro\dodefinepalet
+% \pushmacro\dodefinecolorgroup
+% \def\dodefinecolor[##1][##2]%
+% {\doifassignmentelse{##2}
+% {\getparameters[pstricks][r=0,g=0,b=0,##2]%
+% \expanded{\newrgbcolor{##1}{{\pstricksr} {\pstricksg} {\pstricksb}}}}%
+% {}}%
+% \def\dodefinepalet [##1][##2]{}%
+% \def\dodefinecolorgroup[##1][##2][##3]{}%
+% \writestatus{pstricks}{loading colors from #1}%
+% \input #1 \relax
+% \popmacro\dodefinecolorgroup
+% \popmacro\dodefinepalet
+% \popmacro\dodefinecolor}
+%
+% \input multido \relax
+% \input pstricks \relax
+% \input pst-plot \relax
+%
+% \loadpstrickscolors{colo-rgb}
+
+\definebuffer[PSTRICKS]
+
+\unexpanded\def\processPSTRICKS {\ctxlua{moduledata.pstricks.process(\thebuffernumber{PSTRICKS})}}
+\unexpanded\def\usePSTRICKSmodule[#1]{\ctxlua{moduledata.pstricks.usemodule("#1")}}
+\unexpanded\def\setPSTRICKS #1{\setbuffer[def-\thebuffernumber{PSTRICKS}]#1\endbuffer}
+
+\let\stopPSTRICKS\processPSTRICKS
+
+%D \starttyping
+%D \usemodule[pstricks]
+%D \usePSTRICKSmodule[pst-barcode]
+%D
+%D \startPSTRICKS
+%D \pspicture(-4mm,-1mm)(38mm,26mm)
+%D \psbarcode{9781860742712}{includetext guardwhitespace}{ean13}%
+%D \endpspicture
+%D \stopPSTRICKS
+%D \stoptyping
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv
new file mode 100644
index 000000000..331e90d2e
--- /dev/null
+++ b/tex/context/modules/mkiv/m-punk.mkiv
@@ -0,0 +1,257 @@
+%D \module
+%D [ file=m-punk,
+%D version=2008.04.15,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Punk Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifx\luaversion\undefined \endinput \fi
+
+% At some point the font generation code will move into the
+% ConTeXt MkIV kernel.
+
+\startluacode
+local concat = table.concat
+local chardata = characters.data
+local fontdata = fonts.hashes.identifiers
+
+fonts.mp = fonts.mp or { }
+
+fonts.mp.version = fonts.mp.version or 1.15
+fonts.mp.inline = true
+fonts.mp.cache = containers.define("fonts", "mp", fonts.mp.version, true)
+
+metapost.characters = metapost.characters or { }
+
+-- todo: use table share as in otf
+
+local characters, descriptions = { }, { }
+local factor, l, n, w, h, d, total, variants = 100, { }, 0, 0, 0, 0, 0, 0, true
+
+-- A next version of mplib will provide the tfm font information which
+-- gives better glyph dimensions, plus additional kerning information.
+
+local flusher = {
+ startfigure = function(chrnum,llx,lly,urx,ury)
+ l, n = { }, chrnum
+ w, h, d = urx - llx, ury, -lly
+ total = total + 1
+ inline = fonts.mp.inline
+ end,
+ flushfigure = function(t)
+ for i=1, #t do
+ l[#l+1] = t[i]
+ end
+ end,
+ stopfigure = function()
+ local cd = chardata[n]
+ if inline then
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = { -- todo: xforms, should happen in backend
+ { "special", "pdf: " .. concat(l," ") },
+ }
+ }
+ else
+ descriptions[n] = {
+ -- unicode = n,
+ name = cd and cd.adobename,
+ width = w*100,
+ height = h*100,
+ depth = d*100,
+ boundingbox = { 0, -d, w, h },
+ }
+ characters[n] = {
+ commands = {
+ { "image", { stream = concat(l," "), bbox = { 0, -d*65536, w*65536, h*65536 } } },
+ }
+ }
+ end
+ end
+}
+
+metapost.characters.instances = metapost.characters.instances or 10
+
+function metapost.characters.process(mpxformat, name, instances, scalefactor)
+ statistics.starttiming(metapost.characters)
+ scalefactor = scalefactor or 1
+ instances = instances or metapost.characters.instances or 10
+ local fontname = file.removesuffix(file.basename(name))
+ local hash = file.robustname(string.format("%s %05i %03i", fontname, scalefactor*1000, instances))
+ local lists = containers.read(fonts.mp.cache, hash)
+ if not lists then
+ statistics.starttiming(flusher)
+ -- we can use a format per font
+ local data = io.loaddata(resolvers.findfile(name))
+ metapost.reset(mpxformat)
+ metapost.setoutercolor(2) -- no outer color and no reset either
+ lists = { }
+ for i=1,instances do
+ characters = { }
+ descriptions = { }
+ metapost.process(
+ mpxformat,
+ {
+ "randomseed := " .. i*10 .. ";",
+ "scale_factor := " .. scalefactor .. " ;",
+ data
+ },
+ false,
+ flusher,
+ false,
+ false,
+ "all"
+ )
+ lists[i] = {
+ characters = characters,
+ descriptions = descriptions,
+ parameters = {
+ designsize = 655360,
+ slant = 0,
+ space = 333 * scalefactor,
+ space_stretch = 166.5 * scalefactor,
+ space_shrink = 111 * scalefactor,
+ x_height = 431 * scalefactor,
+ quad = 1000 * scalefactor,
+ extra_space = 0,
+ },
+ properties = {
+ name = string.format("%s-%03i",hash,i),
+ virtualized = true,
+ spacer = "space",
+ }
+ }
+ end
+ metapost.reset(mpxformat) -- saves memory
+ lists = containers.write(fonts.mp.cache, hash, lists)
+ statistics.stoptiming(flusher)
+ end
+ variants = variants + #lists
+ statistics.stoptiming(metapost.characters)
+ return lists
+end
+
+function fonts.handlers.vf.combiner.commands.metafont(g,v)
+ local size = g.specification.size
+ local data = metapost.characters.process(v[2],v[3],v[4],size/655360)
+ local list, t = { }, { }
+ for d=1,#data do
+ t = data[d]
+ t = fonts.constructors.scale(t, -1000)
+ local id = font.nextid()
+ t.fonts = { { id = id } }
+ fontdata[id] = t
+ fonts.handlers.vf.helpers.composecharacters(t)
+ list[d] = font.define(t)
+ end
+ for k, v in next, t do
+ g[k] = v -- kind of replace, when not present, make nil
+ end
+ g.properties.virtualized = true
+ g.variants = list
+end
+
+fonts.definers.methods.install( "punk", {
+ { "metafont", "mfplain", "punkfont.mp", 10 },
+} )
+fonts.definers.methods.install( "punkbold", {
+ { "metafont", "mfplain", "punkfont-bold.mp", 10 },
+} )
+fonts.definers.methods.install( "punkslanted", {
+ { "metafont", "mfplain", "punkfont-slanted.mp", 10 },
+} )
+fonts.definers.methods.install( "punkboldslanted", {
+ { "metafont", "mfplain", "punkfont-boldslanted.mp", 10 },
+} )
+
+-- typesetters.cases.register("RandomPunk", function(current)
+-- local used = fontdata[current].variants
+-- if used then
+-- local f = math.random(1,#used)
+-- current.font = used[f]
+-- return current, true
+-- else
+-- return current, false
+-- end
+-- end)
+
+local getfont = nodes.nuts.getfont
+local setfield = nodes.nuts.setfield
+local random = math.random
+
+typesetters.cases.register("RandomPunk", function(start)
+ local used = fontdata[getfont(start)].variants
+ if used then
+ local f = random(1,#used)
+ setfield(start,"font",used[f])
+ return start, true
+ else
+ return start, false
+ end
+end)
+
+metapost.characters.flusher = flusher
+
+statistics.register("metapost font generation", function()
+ local time = statistics.elapsedtime(flusher)
+ if total > 0 then
+ return string.format("%i glyphs, %.3f seconds runtime, %i glyphs/second", total, time, total/time)
+ else
+ return string.format("%i glyphs, %.3f seconds runtime", total, time)
+ end
+end)
+
+statistics.register("metapost font loading",function()
+ local time = statistics.elapsedtime(metapost.characters)
+ if variants > 0 then
+ return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time)
+ else
+ return string.format("%.3f seconds, %i instances", time, variants)
+ end
+end)
+\stopluacode
+
+\unexpanded\def\EnableRandomPunk {\setcharactercasing[RandomPunk]}
+\unexpanded\def\RandomPunk {\groupedcommand\EnableRandomPunk\donothing}
+\unexpanded\def\StartRandomPunk {\begingroup\EnableRandomPunk}
+\unexpanded\def\StopRandomPunk {\endgroup}
+
+\starttypescript [serif] [punk]
+ \definefontsynonym [Serif] [demo@punk]
+ \definefontsynonym [SerifBold] [demobold@punkbold]
+ \definefontsynonym [SerifSlanted] [demoslanted@punkslanted]
+ \definefontsynonym [SerifBoldSlanted] [demoboldslanted@punkboldslanted]
+ \definefontsynonym [SerifItalic] [SerifSlanted]
+ \definefontsynonym [SerifBoldItalic] [SerifBoldSlanted]
+\stoptypescript
+
+\starttypescript [punk]
+ \definetypeface [punk] [rm] [serif] [punk] [default]
+\stoptypescript
+
+\endinput
+
+\usetypescript[punk]
+
+\setupbodyfont[punk,14pt]
+
+\starttext
+ \definedfont[demo@punk at 10pt]hello world\par
+ \definedfont[demo@punk at 12pt]hello world\par
+ \definedfont[demo@punk at 16pt]hello world\par
+ \definedfont[demo@punk at 20pt]hello world\par
+\stoptext
+
diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv
new file mode 100644
index 000000000..38c2f249e
--- /dev/null
+++ b/tex/context/modules/mkiv/m-scite.mkiv
@@ -0,0 +1,279 @@
+%D \module
+%D [ file=m-scite,
+%D version=2014.04.28,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\SCITE\ lexers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% We can simplify the scite lexers, as long as we're able to return the
+% lexed result table and provide alexer module with the functions that
+% the lexer expects (so I need to decipher the cxx file).
+%
+% lexer._TOKENSTYLES : table
+% lexer._CHILDREN : flag
+% lexer._EXTRASTYLES : table
+% lexer._GRAMMAR : flag
+%
+% lexers.load : function
+% lexers.lex : function
+%
+% And some properties that map styles onto scintilla styling. I get the
+% impression that we end up with something simpler, a hybrid between the
+% scite lexing and the current context way, so we get an intermediate
+% step, with some penalty for context, but at least I don't have to
+% maintain two sets (three sets as we also have a line based series).
+
+% TODO: as these files are in tds we can locate them and set the lexer root
+% to that one. Currently we're on: we're on context/documents.
+
+% TODO: tab
+
+% This is an experiment: eventually we need to hook it into the verbatim code
+% and deal with widow lines and so.
+
+\startluacode
+
+-- todo: merge with collapse
+-- todo: prehash whitespaces
+
+-- todo: hook into the pretty print code
+-- todo: a simple catcode regime with only \ { }
+
+local gsub, sub, find = string.gsub, string.sub, string.find
+local concat = table.concat
+local formatters = string.formatters
+local lpegmatch = lpeg.match
+local setmetatableindex = table.setmetatableindex
+
+local scite = require("util-sci")
+buffers.scite = scite
+
+-- context output:
+
+local f_def_color = formatters["\\definecolor[slxc%s][h=%s%s%s]%%"]
+local f_fore_none = formatters["\\def\\slx%s#1{{\\slxc%s#1}}%%"]
+local f_fore_bold = formatters["\\def\\slx%s#1{{\\slxc%s\\bf#1}}%%"]
+local f_none_bold = formatters["\\def\\slx%s#1{{\\bf#1}}%%"]
+local f_none_none = formatters["\\def\\slx%s#1{{#1}}%%"]
+local f_texstyled = formatters["\\slx%s{%s}"]
+
+local f_mapping = [[
+\let\string\slxL\string\letterleftbrace
+\let\string\slxR\string\letterrightbrace
+\let\string\slxM\string\letterdollar
+\let\string\slxV\string\letterbar
+\let\string\slxU\string\letterhat
+\let\string\slxD\string\letterunderscore
+\let\string\slxH\string\letterhash
+\let\string\slxB\string\letterbackslash
+\let\string\slxP\string\letterpercent
+\let\string\slxT\string\lettertilde
+\let\string\slxS\string\fixedspace
+%]]
+
+local replacer = lpeg.replacer {
+ ["{"] = "\\slxL ",
+ ["}"] = "\\slxR ",
+ ["$"] = "\\slxM ",
+ ["^"] = "\\slxU ",
+ ["_"] = "\\slxD ",
+ ["|"] = "\\slxV ",
+ ["#"] = "\\slxH ",
+ ["\\"] = "\\slxB ",
+ ["%"] = "\\slxP ",
+ ["~"] = "\\slxT ",
+ [" "] = "\\slxS ",
+}
+
+local colors = nil
+
+local function exportcolors()
+ if not colors then
+ scite.loadscitelexer()
+ local function black(f)
+ return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == '00')
+ end
+ local result, r = { f_mapping }, 1
+ for k, v in table.sortedhash(lexer.context.styles) do
+ local fore = v.fore
+ if fore and not black(fore) then
+ r = r + 1
+ result[r] = f_def_color(k,fore[1],fore[2],fore[3])
+ end
+ end
+ r = r + 1
+ result[r] = "%"
+ for k, v in table.sortedhash(lexer.context.styles) do
+ local bold = v.bold
+ local fore = v.fore
+ r = r + 1
+ if fore and not black(fore) then
+ if bold then
+ result[r] = f_fore_bold(k,k)
+ else
+ result[r] = f_fore_none(k,k)
+ end
+ else
+ if bold then
+ result[r] = f_none_bold(k)
+ else
+ result[r] = f_none_none(k)
+ end
+ end
+ end
+ colors = concat(result,"\n")
+ end
+ return colors
+end
+
+local function exportwhites()
+ return setmetatableindex(function(t,k)
+ local v = find(k,"white") and true or false
+ t[k] = v
+ return v
+ end)
+end
+
+local function exportstyled(lexer,text)
+ local result = lexer.lex(lexer,text,0)
+ local start = 1
+ local whites = exportwhites()
+ local buffer = { }
+ for i=1,#result,2 do
+ local style = result[i]
+ local position = result[i+1]
+ local txt = sub(text,start,position-1)
+ txt = lpegmatch(replacer,txt)
+ if whites[style] then
+ buffer[#buffer+1] = txt
+ else
+ buffer[#buffer+1] = f_texstyled(style,txt)
+ end
+ start = position
+ end
+ buffer = concat(buffer)
+ return buffer
+end
+
+function scite.installcommands()
+ context(exportcolors())
+end
+
+local function lexdata(data,lexname)
+ buffers.assign("lex",exportstyled(scite.loadedlexers[lexname],data or ""))
+end
+
+scite.lexdata = lexdata
+
+function scite.lexbuffer(name,lexname)
+ lexdata(buffers.getcontent(name) or "",lexname or "tex")
+end
+
+function scite.lexfile(filename,lexname)
+ lexdata(io.loaddata(filename) or "",lexname or file.suffix(filename))
+end
+
+-- html output
+
+\stopluacode
+
+% This is a preliminary interface.
+
+\unprotect
+
+\unexpanded\def\installscitecommands
+ {\ctxlua{buffers.scite.installcommands()}%
+ \let\installscitecommands\relax}
+
+\unexpanded\def\startscite{\startlines}
+\unexpanded\def\stopscite {\stoplines}
+
+\unexpanded\def\scitefile
+ {\dosingleargument\module_scite_file}
+
+\unexpanded\def\module_scite_file[#1]%
+ {\start
+ \ctxlua{buffers.scite.lexfile("#1")}%
+ \installscitecommands
+ \tt
+ \dontcomplain
+ \setcatcodetable\ctxcatcodes % needed in xml
+ \startscite
+ \getbuffer[lex]%
+ \stopscite
+ \stop}
+
+\unexpanded\def\scitebuffer
+ {\dodoubleargument\module_scite_buffer}
+
+\unexpanded\def\module_scite_buffer[#1][#2]%
+ {\start
+ \ifsecondargument
+ \ctxlua{buffers.scite.lexbuffer("#2","#1")}%
+ \else
+ \ctxlua{buffers.scite.lexbuffer("#1","tex")}%
+ \fi
+ \installscitecommands
+ \tt
+ \dontcomplain
+ \setcatcodetable\ctxcatcodes % needed in xml
+ \startscite
+ \getbuffer[lex]%
+ \stopscite
+ \stop}
+
+\protect
+
+\continueifinputfile{m-scite.mkiv}
+
+\setupbodyfont[dejavu,8pt]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ header=1cm,
+ footer=1cm,
+ topspace=1cm,
+ bottomspace=1cm,
+ backspace=1cm]
+
+\startbuffer[demo]
+\startsubsubject[title={oeps}]
+
+\startMPcode
+ draw fullcircle
+ scaled 2cm
+ withpen pencircle scaled 1mm
+ withcolor .5green;
+ draw textext (
+ lua (
+ "local function f(s) return string.upper(s) end mp.quoted(f('foo'))"
+ )
+ ) withcolor .5red ;
+\stopMPcode
+
+\startluacode
+ context("foo")
+\stopluacode
+
+\stopsubsubject
+\stopbuffer
+
+\starttext
+
+% \scitefile[../lexers/scite-context-lexer.lua] \page
+% \scitefile[t:/manuals/about/about-metafun.tex] \page
+% \scitefile[t:/sources/strc-sec.mkiv] \page
+% \scitefile[e:/tmp/mp.w] \page
+% \scitefile[t:/manuals/hybrid/tugboat.bib] \page
+\scitefile[e:/tmp/test.bib] \page
+
+% \getbuffer[demo] \scitebuffer[demo]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-spreadsheet.lua b/tex/context/modules/mkiv/m-spreadsheet.lua
new file mode 100644
index 000000000..1b3c5cb34
--- /dev/null
+++ b/tex/context/modules/mkiv/m-spreadsheet.lua
@@ -0,0 +1,332 @@
+if not modules then modules = { } end modules ['m-spreadsheet'] = {
+ version = 1.001,
+ comment = "companion to m-spreadsheet.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local byte, format, gsub, find = string.byte, string.format, string.gsub, string.find
+local R, P, S, C, V, Cs, Cc, Ct, Cg, Cf, Carg = lpeg.R, lpeg.P, lpeg.S, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Carg
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local setmetatable, loadstring, next, tostring, tonumber,rawget = setmetatable, loadstring, next, tostring, tonumber, rawget
+local formatters = string.formatters
+
+local context = context
+
+local splitthousands = utilities.parsers.splitthousands
+local variables = interfaces.variables
+
+local v_yes = variables.yes
+
+moduledata = moduledata or { }
+
+local spreadsheets = { }
+moduledata.spreadsheets = spreadsheets
+
+local data = {
+ -- nothing yet
+}
+
+local settings = {
+ period = ".",
+ comma = ",",
+}
+
+spreadsheets.data = data
+spreadsheets.settings = settings
+
+local defaultname = "default"
+local stack = { }
+local current = defaultname
+
+local d_mt ; d_mt = {
+ __index = function(t,k)
+ local v = { }
+ setmetatable(v,d_mt)
+ t[k] = v
+ return v
+ end,
+}
+
+local s_mt ; s_mt = {
+ __index = function(t,k)
+ local v = settings[k]
+ t[k] = v
+ return v
+ end,
+}
+
+function spreadsheets.setup(t)
+ for k, v in next, t do
+ settings[k] = v
+ end
+end
+
+local function emptydata(name,settings)
+ local data = { }
+ local specifications = { }
+ local settings = settings or { }
+ setmetatable(data,d_mt)
+ setmetatable(specifications,d_mt)
+ setmetatable(settings,s_mt)
+ return {
+ name = name,
+ data = data,
+ maxcol = 0,
+ maxrow = 0,
+ settings = settings,
+ temp = { }, -- for local usage
+ specifications = specifications,
+ }
+end
+
+function spreadsheets.reset(name)
+ if not name or name == "" then name = defaultname end
+ data[name] = emptydata(name,data[name] and data[name].settings)
+end
+
+function spreadsheets.start(name,s)
+ if not name or name == "" then
+ name = defaultname
+ end
+ if not s then
+ s = { }
+ end
+ table.insert(stack,current)
+ current = name
+ if data[current] then
+ setmetatable(s,s_mt)
+ data[current].settings = s
+ else
+ data[current] = emptydata(name,s)
+ end
+end
+
+function spreadsheets.stop()
+ current = table.remove(stack)
+end
+
+spreadsheets.reset()
+
+local offset = byte("A") - 1
+
+local function assign(s,n)
+ return formatters["moduledata.spreadsheets.data['%s'].data[%s]"](n,byte(s)-offset)
+end
+
+function datacell(a,b,...)
+ local n = 0
+ if b then
+ local t = { a, b, ... }
+ for i=1,#t do
+ n = n * (i-1) * 26 + byte(t[i]) - offset
+ end
+ else
+ n = byte(a) - offset
+ end
+ return formatters["dat[%s]"](n)
+end
+
+local function checktemplate(s)
+ if find(s,"%",1,true) then
+ -- normal template
+ return s
+ elseif find(s,"@",1,true) then
+ -- tex specific template
+ return gsub(s,"@","%%")
+ else
+ -- tex specific quick template
+ return "%" .. s
+ end
+end
+
+local quoted = Cs(patterns.unquoted)
+local spaces = patterns.whitespace^0
+local cell = C(R("AZ"))^1 / datacell * (Cc("[") * (R("09")^1) * Cc("]") + #P(1))
+
+-- A nasty aspect of lpeg: Cf ( spaces * Cc("") * { "start" ... this will create a table that will
+-- be reused, so we accumulate!
+
+local pattern = Cf ( spaces * Ct("") * { "start",
+ start = V("value") + V("set") + V("format") + V("string") + V("code"),
+ value = Cg(P([[=]]) * spaces * Cc("kind") * Cc("value")) * V("code"),
+ set = Cg(P([[!]]) * spaces * Cc("kind") * Cc("set")) * V("code"),
+ format = Cg(P([[@]]) * spaces * Cc("kind") * Cc("format")) * spaces * Cg(Cc("template") * Cs(quoted/checktemplate)) * V("code"),
+ string = Cg(#S([["']]) * Cc("kind") * Cc("string")) * Cg(Cc("content") * quoted),
+ code = spaces * Cg(Cc("code") * Cs((cell + P(1))^0)),
+}, rawset)
+
+local functions = { }
+spreadsheets.functions = functions
+
+function functions._s_(row,col,c,f,t)
+ local r = 0
+ if f and t then -- f..t
+ -- ok
+ elseif f then -- 1..f
+ f, t = 1, f
+ else
+ f, t = 1, row - 1
+ end
+ for i=f,t do
+ local ci = c[i]
+ if type(ci) == "number" then
+ r = r + ci
+ end
+ end
+ return r
+end
+
+functions.fmt = string.tformat
+
+local f_code = formatters [ [[
+ local _m_ = moduledata.spreadsheets
+ local dat = _m_.data['%s'].data
+ local tmp = _m_.temp
+ local fnc = _m_.functions
+ local row = %s
+ local col = %s
+ function fnc.sum(...) return fnc._s_(row,col,...) end
+ local sum = fnc.sum
+ local fmt = fnc.fmt
+ return %s
+]] ]
+
+-- to be considered: a weak cache
+
+local function propername(name)
+ if name ~= "" then
+ return name
+ elseif current ~= "" then
+ return current
+ else
+ return defaultname
+ end
+end
+
+-- if name == "" then name = current if name == "" then name = defaultname end end
+
+local function execute(name,r,c,str)
+ if str ~= "" then
+ local d = data[name]
+ if c > d.maxcol then
+ d.maxcol = c
+ end
+ if r > d.maxrow then
+ d.maxrow = r
+ end
+ local specification = lpegmatch(pattern,str,1,name)
+ d.specifications[c][r] = specification
+ local kind = specification.kind
+ if kind == "string" then
+ return specification.content or ""
+ else
+ local code = specification.code
+ if code and code ~= "" then
+ code = f_code(name,r,c,code or "")
+ local result = loadstring(code) -- utilities.lua.strippedloadstring(code,true) -- when tracing
+ result = result and result()
+ if type(result) == "function" then
+ result = result()
+ end
+ if type(result) == "number" then
+ d.data[c][r] = result
+ end
+ if not result then
+ -- nothing
+ elseif kind == "set" then
+ -- no return
+ elseif kind == "format" then
+ return formatters[specification.template](result)
+ else
+ return result
+ end
+ end
+ end
+ end
+end
+
+function spreadsheets.set(name,r,c,str)
+ name = propername(name)
+ execute(name,r,c,str)
+end
+
+function spreadsheets.get(name,r,c,str)
+ name = propername(name)
+ local dname = data[name]
+ if not dname then
+ -- nothing
+ elseif not str or str == "" then
+ context(dname.data[c][r] or 0)
+ else
+ local result = execute(name,r,c,str)
+ if result then
+-- if type(result) == "number" then
+-- dname.data[c][r] = result
+-- result = tostring(result)
+-- end
+ local settings = dname.settings
+ local split = settings.split
+ local period = settings.period
+ local comma = settings.comma
+ if split == v_yes then
+ result = splitthousands(result)
+ end
+ if period == "" then period = nil end
+ if comma == "" then comma = nil end
+ result = gsub(result,".",{ ["."] = period, [","] = comma })
+ context(result)
+ end
+ end
+end
+
+function spreadsheets.doifelsecell(name,r,c)
+ name = propername(name)
+ local d = data[name]
+ local d = d and d.data
+ local r = d and rawget(d,r)
+ local c = r and rawget(r,c)
+ commands.doifelse(c)
+end
+
+local function simplify(name)
+ name = propername(name)
+ local data = data[name]
+ if data then
+ data = data.data
+ local temp = { }
+ for k, v in next, data do
+ local t = { }
+ temp[k] = t
+ for kk, vv in next, v do
+ if type(vv) == "function" then
+ t[kk] = "<function>"
+ else
+ t[kk] = vv
+ end
+ end
+ end
+ return temp
+ end
+end
+
+local function serialize(name)
+ local s = simplify(name)
+ if s then
+ return table.serialize(s,name)
+ else
+ return formatters["<unknown spreadsheet %a>"](name)
+ end
+end
+
+spreadsheets.simplify = simplify
+spreadsheets.serialize = serialize
+
+function spreadsheets.inspect(name)
+ inspect(serialize(name))
+end
+
+function spreadsheets.tocontext(name)
+ context.tocontext(simplify(name))
+end
diff --git a/tex/context/modules/mkiv/m-spreadsheet.mkiv b/tex/context/modules/mkiv/m-spreadsheet.mkiv
new file mode 100644
index 000000000..914a2b57a
--- /dev/null
+++ b/tex/context/modules/mkiv/m-spreadsheet.mkiv
@@ -0,0 +1,221 @@
+%D \module
+%D [ file=m-spreadsheet,
+%D version=2011.02.21,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Spreadsheets,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is an experimental follow up on discussion on the mailing list.
+
+\registerctxluafile{m-spreadsheet}{1.001}
+
+\unprotect
+
+% todo: get(...) set(..) ctx(...)
+
+\installcorenamespace{spreadsheet}
+
+\installcommandhandler \??spreadsheet {spreadsheet} \??spreadsheet
+
+\appendtoks
+ \ctxlua{moduledata.spreadsheets.setup{ % global !
+ period = \!!bs\spreadsheetparameter\c!period\!!es,
+ comma = \!!bs\spreadsheetparameter\c!comma\!!es,
+ split = \!!bs\spreadsheetparameter\c!split\!!es,
+ }}%
+\to \everysetupspreadsheet
+
+\setupspreadsheet
+ [%\c!comma=,
+ %\c!period=,
+ \c!split=\v!no]
+
+\unexpanded\def\resetspreadsheet
+ {\dosingleempty\module_spreadsheet_reset}
+
+\unexpanded\def\module_spreadsheet_reset[#1]%
+ {\ctxlua{moduledata.spreadsheets.reset("#1")}}
+
+\unexpanded\def\startspreadsheet
+ {\dosingleempty\module_spreadsheet_start}
+
+\unexpanded\def\module_spreadsheet_start[#1]%
+ {\pushmacro\currentspreadsheet
+ \edef\currentspreadsheet{#1}%
+ \checkspreadsheetparent
+ \edef\m_spreadsheet_period{\spreadsheetparameter\c!period}%
+ \edef\m_spreadsheet_comma {\spreadsheetparameter\c!comma}%
+ \ctxlua{moduledata.spreadsheets.start("#1", {
+ period = \!!bs\detokenize\expandafter{\m_spreadsheet_period}\!!es,
+ comma = \!!bs\detokenize\expandafter{\m_spreadsheet_comma}\!!es,
+ split = \!!bs\spreadsheetparameter\c!split\!!es,
+ })}}
+
+\unexpanded\def\stopspreadsheet
+ {\ctxlua{moduledata.spreadsheets.stop()}%
+ \popmacro\currentspreadsheet}
+
+\unexpanded\def\showspreadsheet
+ {\dosingleempty\module_spreadsheet_show}
+
+\unexpanded\def\module_spreadsheet_show[#1]%
+ {\ctxlua{moduledata.spreadsheets.tocontext("#1")}}
+
+\unexpanded\def\inspectspreadsheet
+ {\dosingleempty\module_spreadsheet_inspect}
+
+\unexpanded\def\module_spreadsheet_inspect[#1]%
+ {\ctxlua{moduledata.spreadsheets.inspect("#1")}}
+
+\unexpanded\def\setspreadsheet
+ {\dosingleempty\module_spreadsheet_set}
+
+\unexpanded\def\module_spreadsheet_set[#1]#2#3#4%
+ {\ctxlua{moduledata.spreadsheets.set("#1",\number#2,\number#3,"#4")}}
+
+\unexpanded\def\getspreadsheet
+ {\dosingleempty\module_spreadsheet_get}
+
+\unexpanded\def\module_spreadsheet_get[#1]#2#3#4%
+ {\ctxlua{moduledata.spreadsheets.get("#1",\number#2,\number#3,"#4")}}
+
+\unexpanded\def\doifelsespreadsheetcell
+ {\dosingleempty\module_spreadsheet_doifelse_cell}
+
+\let\doifspreadsheetcellelse\doifelsespreadsheetcell
+
+\unexpanded\def\module_spreadsheet_doifelse_cell[#1]#2#3%
+ {\ctxlua{moduledata.spreadsheets.doifelsecell("#1",\number#2,\number#3)}}
+
+\ifdefined\tblrow
+
+ \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
+ \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\tblrow+1,\number\tblcol,\!!bs#1\!!es)}}
+
+\else
+
+ \def\TABLEsetspreadsheet#1{\ctxlua{moduledata.spreadsheets.set("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}}
+ \def\TABLEgetspreadsheet#1{\ctxlua{moduledata.spreadsheets.get("",\number\c_tabl_ntb_row+1,\number\c_tabl_ntb_col,\!!bs#1\!!es)}}
+
+\fi
+
+\appendtoks
+ \module_spreadsheet_reset[\currentspreadsheet]%
+ \let\setspr\TABLEsetspreadsheet
+ \let\getspr\TABLEgetspreadsheet
+\to \everyTABLEpass
+
+\unexpanded\def\startspreadsheettable % quick and dirty
+ {\dodoubleempty\module_spreadsheet_start_table}
+
+\unexpanded\def\module_spreadsheet_start_table[#1][#2]%
+ {\bgroup
+ \let\startrow \module_spreadsheet_row_start
+ \let\stoprow \module_spreadsheet_row_stop
+ \let\startcell\module_spreadsheet_cell_start
+ \let\stopcell \module_spreadsheet_cell_stop
+ \doifelseassignment{#1}
+ {\module_spreadsheet_start
+ \directsetup{spreadsheet:before:\currentspreadsheet}%
+ \bTABLE[\c!align=\v!flushright,#1]}
+ {\module_spreadsheet_start[#1]%
+ \directsetup{spreadsheet:before:\currentspreadsheet}%
+ \bTABLE[\c!align=\v!flushright,#2]}}
+
+\unexpanded\def\stopspreadsheettable
+ {\eTABLE
+ \directsetup{spreadsheet:after:\currentspreadsheet}%
+ \stopspreadsheet
+ \egroup}
+
+\unexpanded\def\module_spreadsheet_row_start{\bTR}
+\unexpanded\def\module_spreadsheet_row_stop {\eTR}
+
+\unexpanded\def\module_spreadsheet_cell_start
+ {\doifelsenextoptional\module_spreadsheet_cell_start_yes\module_spreadsheet_cell_start_nop}
+
+\unexpanded\def\module_spreadsheet_cell_start_yes[#1]#2\stopcell
+ {\bTD[#1]\getspr{#2}\eTD}
+
+\unexpanded\def\module_spreadsheet_cell_start_nop#1\stopcell
+ {\bTD\getspr{#1}\eTD}
+
+\let\module_spreadsheet_cell_stop\relax
+
+\protect
+
+\continueifinputfile{m-spreadsheet.mkiv}
+
+\starttext
+
+\bTABLE[align=middle]
+ \bTR
+ \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD
+ \eTR
+ \bTR
+ \bTD \getspr{20} \eTD \bTD \getspr{4+3} \eTD
+ \eTR
+ \bTR
+ \bTD \getspr{A[1] + A[2]} \eTD
+ \bTD \getspr{B1 + B2} \eTD
+ \eTR
+ \bTR
+ \bTD[nx=2] \bf \getspr{(A[3] + B[3]) /100} \eTD
+ \eTR
+ \bTR
+ \bTD[nx=2] \bf \getspr{string.format("\letterpercent0.3f",(A[3] + B[3]) /100)} \eTD
+ \eTR
+ \bTR
+ \bTD[nx=2] \bf \getspr{fmt("@0.3f",(sum(A,1,2)) / 10)} \eTD
+ \eTR
+\eTABLE
+
+\setupspreadsheet[mysheet]
+
+\startspreadsheet[mysheet]
+
+\bTABLE[align=middle]
+ \bTR
+ \bTD \getspr{100} \eTD \bTD test \setspr{30} \eTD
+ \eTR
+ \bTR
+ \bTD \getspr{20} \eTD \bTD \getspr{4+3.5} \eTD
+ \eTR
+ \bTR
+ \bTD \getspr{A[1] + A[2]} \eTD
+ \bTD \getspr{B[1] + B[2]} \eTD
+ \eTR
+ \bTR
+ \bTD[nx=2] \bf \getspr{A[3] + B[3]} \eTD
+ \eTR
+\eTABLE
+
+\stopspreadsheet
+
+\blank
+
+\setupspreadsheet[test][period={{\bf\middlered .}},comma={{\bf\middlegreen ,}},split=yes]
+
+\startspreadsheettable[test]
+ \startrow
+ \startcell 123456.78 \stopcell
+ \startcell 1234567.89 \stopcell
+ \startcell A[1] + B[1] \stopcell
+ \stoprow
+\stopspreadsheettable
+
+\blank
+
+% \showspreadsheet
+% \showspreadsheet[mysheet]
+
+\doifelsespreadsheetcell[mysheet]{1}{2}{YES}{NOP}
+\doifelsespreadsheetcell[myshoot]{1}{2}{YES}{NOP}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-sql.mkiv b/tex/context/modules/mkiv/m-sql.mkiv
new file mode 100644
index 000000000..f1df2833a
--- /dev/null
+++ b/tex/context/modules/mkiv/m-sql.mkiv
@@ -0,0 +1,29 @@
+%D \module
+%D [ file=m-sql,
+%D version=2012.07.12,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=SQL,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[sql]
+
+\registerctxluafile{util-tpl}{}
+\registerctxluafile{util-sql}{}
+
+\setupmodule
+
+\doifsomething {\currentmoduleparameter{method}}{
+ \ctxlua{utilities.sql.setmethod("\currentmoduleparameter{method}")}
+}
+
+\doifsomething {\currentmoduleparameter{server}} {
+ \ctxlua{utilities.sql.setserver("\currentmoduleparameter{server}")}
+}
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/m-steps.lua b/tex/context/modules/mkiv/m-steps.lua
new file mode 100644
index 000000000..8eb481550
--- /dev/null
+++ b/tex/context/modules/mkiv/m-steps.lua
@@ -0,0 +1,226 @@
+if not modules then modules = { } end modules ['x-flow'] = {
+ version = 1.001,
+ comment = "companion to m-flow.mkvi",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- when we can resolve mpcolor at the lua end we will use metapost.graphic(....) directly
+
+moduledata.steps = moduledata.steps or { }
+
+local variables = interfaces.variables
+
+local trace_charts = false
+
+local defaults = {
+ chart = {
+ dx = 10*65436,
+ dy = 10*65436,
+ },
+ cell = {
+ alternative = 1,
+ offset = 2*65436,
+ rulethickness = 65436,
+ framecolor = "blue",
+ backgroundcolor = "gray",
+ },
+ text = {
+ alternative = 1,
+ offset = 2*65436,
+ distance = 4*65436,
+ rulethickness = 65436,
+ framecolor = "red",
+ backgroundcolor = "gray",
+ },
+ line = {
+ alternative = 1,
+ rulethickness = 65436,
+ height = 30*65436,
+ distance = 10*65436,
+ offset = 5*65436,
+ color = "green",
+ },
+}
+
+-- todo : name (no name then direct)
+-- maybe: includes
+-- maybe: flush ranges
+
+local charts = { }
+local steps = { }
+
+function commands.step_start_chart(name)
+ name = name or ""
+ steps = { }
+ charts[name] = {
+ steps = steps,
+ }
+end
+
+function commands.step_stop_chart()
+end
+
+function commands.step_make_chart(settings)
+ local chartsettings = settings.chart
+ if not chartsettings then
+ print("no chart")
+ return
+ end
+ local chartname = chartsettings.name
+ if not chartname then
+ print("no name given")
+ return
+ end
+ local chart = charts[chartname]
+ if not chart then
+ print("no such chart",chartname)
+ return
+ end
+ local steps = chart.steps or { }
+ --
+ table.setmetatableindex(settings,defaults)
+ --
+ if trace_charts then
+ inspect(steps)
+ end
+ --
+ local textsettings = settings.text
+ local cellsettings = settings.cell
+ local linesettings = settings.line
+ --
+ context.startMPcode()
+ context("if unknown context_cell : input mp-step.mpiv ; fi ;")
+ context("step_begin_chart ;")
+ --
+ if chartsettings.alternative == variables.vertical then
+ context("chart_vertical := true ;")
+ end
+ --
+ context("text_line_color := \\MPcolor{%s} ;", textsettings.framecolor)
+ context("text_line_width := %p ;", textsettings.rulethickness)
+ context("text_fill_color := \\MPcolor{%s} ;", textsettings.backgroundcolor)
+ context("text_offset := %p ;", textsettings.offset)
+ context("text_distance_set := %p ;", textsettings.distance)
+ --
+ context("cell_line_color := \\MPcolor{%s} ;", cellsettings.framecolor)
+ context("cell_line_width := %p ;", cellsettings.rulethickness)
+ context("cell_fill_color := \\MPcolor{%s} ;", cellsettings.backgroundcolor)
+ context("cell_offset := %p ;", cellsettings.offset)
+ context("cell_distance_x := %p ;", cellsettings.dx)
+ context("cell_distance_y := %p ;", cellsettings.dy)
+ --
+ context("line_line_color := \\MPcolor{%s} ;", linesettings.color)
+ context("line_line_width := %p ;", linesettings.rulethickness)
+ context("line_distance := %p ;", linesettings.distance)
+ context("line_offset := %p ;", linesettings.offset)
+ --
+ for i=1,#steps do
+ local step = steps[i]
+ context("step_begin_cell ;")
+ if step.cell_top ~= "" then
+ context('step_cell_top("%s") ;',string.strip(step.cell_top))
+ end
+ if step.cell_bot ~= "" then
+ context('step_cell_bot("%s") ;',string.strip(step.cell_bot))
+ end
+ if step.text_top ~= "" then
+ context('step_text_top("%s") ;',string.strip(step.text_top))
+ end
+ if step.text_mid ~= "" then
+ context('step_text_mid("%s") ;',string.strip(step.text_mid))
+ end
+ if step.text_bot ~= "" then
+ context('step_text_bot("%s") ;',string.strip(step.text_bot))
+ end
+ context("step_end_cell ;")
+ end
+ --
+ context("step_end_chart ;")
+ context.stopMPcode()
+end
+
+function commands.step_cells(top,bot)
+ steps[#steps+1] = {
+ cell_top = top or "",
+ cell_bot = bot or "",
+ text_top = "",
+ text_mid = "",
+ text_bot = "",
+ }
+end
+
+function commands.step_texts(top,bot)
+ if #steps > 0 then
+ steps[#steps].text_top = top or ""
+ steps[#steps].text_bot = bot or ""
+ end
+end
+
+function commands.step_cell(top)
+ steps[#steps+1] = {
+ cell_top = top or "",
+ cell_bot = "",
+ text_top = "",
+ text_mid = "",
+ text_bot = "",
+ }
+end
+
+function commands.step_text(top)
+ if #steps > 0 then
+ steps[#steps].text_top = top or ""
+ end
+end
+
+function commands.step_textset(left,middle,right)
+ if #steps > 0 then
+ steps[#steps].text_top = left or ""
+ steps[#steps].text_mid = middle or ""
+ steps[#steps].text_bot = right or ""
+ end
+end
+
+function commands.step_start_cell()
+ steps[#steps+1] = {
+ cell_top = "",
+ cell_bot = "",
+ text_top = "",
+ text_mid = "",
+ text_bot = "",
+ }
+end
+
+function commands.step_stop_cell()
+end
+
+function commands.step_text_top(str)
+ if #steps > 0 then
+ steps[#steps].text_top = str or ""
+ end
+end
+
+function commands.step_text_mid(str)
+ if #steps > 0 then
+ steps[#steps].text_mid = str or ""
+ end
+end
+
+function commands.step_text_bot(str)
+ if #steps > 0 then
+ steps[#steps].text_bot = str or ""
+ end
+end
+
+function commands.step_cell_top(str)
+ if #steps > 0 then
+ steps[#steps].cell_top = str or ""
+ end
+end
+
+function commands.step_cell_bot(str)
+ if #steps > 0 then
+ steps[#steps].cell_bot = str or ""
+ end
+end
diff --git a/tex/context/modules/mkiv/m-steps.mkvi b/tex/context/modules/mkiv/m-steps.mkvi
new file mode 100644
index 000000000..c9c5a0636
--- /dev/null
+++ b/tex/context/modules/mkiv/m-steps.mkvi
@@ -0,0 +1,382 @@
+%D \module
+%D [ file=m-steps,
+%D version=2011.10.07, % 2001.05.28,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Step Charts \& Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% multiple texts?
+
+\registerctxluafile{m-steps}{}
+
+\unprotect
+
+\installcorenamespace {stepcharts}
+\installcorenamespace {steptables}
+\installcorenamespace {stepcells}
+\installcorenamespace {steptexts}
+\installcorenamespace {steplines}
+
+\installsimplecommandhandler \??stepcharts {STEPchart} \??stepcharts
+\installsimplecommandhandler \??steptables {STEPtable} \??steptables
+\installsimplecommandhandler \??stepcells {STEPcell} \??stepcells
+\installsimplecommandhandler \??steptexts {STEPtext} \??steptexts
+\installsimplecommandhandler \??steplines {STEPline} \??steplines
+
+\let\setupSTEPcharts\setupSTEPchart
+\let\setupSTEPtables\setupSTEPtable
+\let\setupSTEPcells \setupSTEPcell
+\let\setupSTEPtexts \setupSTEPtext
+\let\setupSTEPlines \setupSTEPline
+
+% numeric text_text_distance ; text_text_distance := 20pt ;
+% numeric step_distance ; step_distance := 20pt ;
+
+\setupSTEPcharts
+ [\c!alternative=\v!horizontal,
+ \c!before=\blank,
+ \c!after=\blank]
+% \c!offset=.15\bodyfontsize
+% \c!height=2ex
+
+% \setupSTEPtables
+% [\c!before=\blank,
+% \c!after=\blank,
+% \c!distance=.25em,
+% \c!voffset=1ex,
+% \c!method=1,
+% \c!width=4em,
+% \c!offset=.15\bodyfontsize]
+
+\setupSTEPcells
+ [\c!alternative=1, % TODO
+% \c!style=,
+% \c!color=,
+ \c!dx=\bodyfontsize,
+ \c!dy=\bodyfontsize,
+ \c!background=\v!color,
+ \c!backgroundcolor=STEPbackgroundcolor,
+ \c!rulethickness=.1\bodyfontsize,
+ \c!framecolor=STEPframecolor,
+ \c!offset=.25\bodyfontsize]
+
+\setupSTEPtexts
+ [\c!alternative=1, % TODO
+% \c!style=\v!smallbodyfont,
+% \c!color=,
+ \c!background=\v!color,
+ \c!backgroundcolor=STEPbackgroundcolor,
+ \c!rulethickness=.1\bodyfontsize,
+ \c!framecolor=STEPframecolor,
+ \c!distance=.5\bodyfontsize,
+ \c!offset=.25\bodyfontsize]
+
+\setupSTEPlines
+ [\c!alternative=1, % TODO
+ \c!rulethickness=.15\bodyfontsize,
+ \c!height=3\bodyfontsize,
+ \c!distance=.5\bodyfontsize,
+ \c!offset=.25\bodyfontsize,
+ \c!color=STEPlinecolor]
+
+\definecolor [STEPlinecolor] [s=.5]
+\definecolor [STEPframecolor] [s=.7]
+\definecolor [STEPbackgroundcolor] [s=.9]
+
+\newtoks\everySTEPchart
+
+\unexpanded\def\startSTEPchart
+ {\begingroup
+ \dodoubleempty\module_steps_start_chart}
+
+\def\module_steps_start_chart[#name][#settings]%
+ {\startnointerference
+ \iffirstargument
+ \doifelseassignment{#name}
+ {\let\currentSTEPchart\empty
+ \xdef\module_steps_flush_chart{\module_steps_chart[][#name]}}
+ {\edef\currentSTEPchart{#name}%
+ \glet\module_steps_flush_chart\relax}% settings are not stored
+ \else
+ \let\currentSTEPchart\empty
+ \gdef\module_steps_flush_chart{\module_steps_chart[][]}%
+ \fi
+ \the\everySTEPchart
+ \ctxcommand{step_start_chart("\currentSTEPchart")}}
+
+\unexpanded\def\stopSTEPchart
+ {\ctxcommand{step_stop_chart()}%
+ \stopnointerference
+ \module_steps_flush_chart
+ \endgroup}
+
+\unexpanded\def\startSTEPtable
+ {\begingroup
+ \setupSTEPchart[\c!alternative=\v!vertical]%
+ \dodoubleempty\module_steps_start_chart}
+
+\let\stopSTEPtable\stopSTEPchart
+
+\let\module_steps_flush_chart\relax
+
+\unexpanded\def\STEPchart
+ {\dodoubleempty\module_steps_chart}
+
+\unexpanded\def\module_steps_chart[#name][#settings]%
+ {\begingroup
+ \setupSTEPchart[#settings]%
+ \ifinsidefloat
+ \makeSTEPchart[#name]%
+ \else
+ \STEPchartparameter\c!before
+ \startbaselinecorrection
+ \setlocalhsize
+ \makeSTEPchart[#name]%
+ \stopbaselinecorrection
+ \STEPchartparameter\c!after
+ \fi
+ \endgroup}
+
+\unexpanded\def\makeSTEPchart[#name]%
+ {\ctxcommand{step_make_chart {
+ chart = {
+ name = "#name",
+ alternative = "\STEPchartparameter\c!alternative",
+ },
+ cell = {
+ alternative = "\STEPcellparameter\c!alternative", % TODO: shapes
+ offset = \number\dimexpr\STEPcellparameter\c!offset,
+ rulethickness = \number\dimexpr\STEPcellparameter\c!rulethickness,
+ framecolor = "\STEPcellparameter\c!framecolor",
+ backgroundcolor = "\STEPcellparameter\c!backgroundcolor",
+ dx = \number\dimexpr\STEPcellparameter\c!dx,
+ dy = \number\dimexpr\STEPcellparameter\c!dy,
+ },
+ text = {
+ alternative = "\STEPtextparameter\c!alternative", % TODO: shapes
+ offset = \number\dimexpr\STEPtextparameter\c!offset,
+ distance = \number\dimexpr\STEPtextparameter\c!distance,
+ rulethickness = \number\dimexpr\STEPtextparameter\c!rulethickness,
+ framecolor = "\STEPtextparameter\c!framecolor",
+ backgroundcolor = "\STEPtextparameter\c!backgroundcolor",
+ },
+ line = {
+ alternative = "\STEPlineparameter\c!alternative", % TODO: dash, arrow
+ rulethickness = \number\dimexpr\STEPlineparameter\c!rulethickness,
+ height = \number\dimexpr\STEPlineparameter\c!height,
+ distance = \number\dimexpr\STEPlineparameter\c!distance,
+ offset = \number\dimexpr\STEPlineparameter\c!offset,
+ color = "\STEPlineparameter\c!color",
+ },
+ }}}
+
+\unexpanded\def\startSTEPcell
+ {\ctxcommand{step_start_cell()}}
+
+\unexpanded\def\stopSTEPcell
+ {\ctxcommand{step_stop_cell()}}
+
+\unexpanded\def\module_steps_cells#top#bot%
+ {\ctxcommand{step_cells(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}}
+
+\unexpanded\def\module_steps_texts#top#bot%
+ {\ctxcommand{step_texts(\!!bs\detokenize{#top}\!!es,\!!bs\detokenize{#bot}\!!es)}}
+
+\unexpanded\def\module_steps_cell#str%
+ {\ctxcommand{step_cell(\!!bs\detokenize{#str}\!!es)}}
+
+\unexpanded\def\module_steps_text#str%
+ {\ctxcommand{step_text(\!!bs\detokenize{#str}\!!es)}}
+
+\unexpanded\def\module_steps_textset#left#middle#right%
+ {\ctxcommand{step_textset(\!!bs\detokenize{#left}\!!es,\!!bs\detokenize{#middle}\!!es,\!!bs\detokenize{#right}\!!es)}}
+
+\unexpanded\def\module_steps_toptext#top%
+ {\ctxcommand{step_text_top(\!!bs\detokenize{#top}\!!es)}}
+
+\unexpanded\def\module_steps_bottext#bot%
+ {\ctxcommand{step_text_bot(\!!bs\detokenize{#bot}\!!es)}}
+
+\unexpanded\def\module_steps_topcell#top%
+ {\ctxcommand{step_cell_top(\!!bs\detokenize{#top}\!!es)}}
+
+\unexpanded\def\module_steps_botcell#bot%
+ {\ctxcommand{step_cell_bot(\!!bs\detokenize{#bot}\!!es)}}
+
+\appendtoks
+ \let\cells \module_steps_cells
+ \let\texts \module_steps_texts
+ \let\cell \module_steps_cell
+ \let\text \module_steps_text
+ \let\textset\module_steps_textset
+ \let\toptext\module_steps_toptext
+ \let\bottext\module_steps_bottext
+ \let\topcell\module_steps_topcell
+ \let\botcell\module_steps_botcell
+\to \everySTEPchart
+
+% todo: mapping can be done in lua
+
+\startxmlsetups xml:step:define
+ \xmlsetsetup{#1} {stepchart|steptable} {xml:step:*}
+\stopxmlsetups
+
+\xmlregistersetup{xml:step:define}
+
+\startxmlsetups xml:step:stepchart
+ \startSTEPchart
+ \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)}
+ \stopSTEPchart
+\stopxmlsetups
+
+\startxmlsetups xml:step:steptable
+ \startSTEPtable
+ \xmlfilter{#1}{/(cells|texts|stepcell|cell|text)/command(xml:step:*)}
+ \stopSTEPtable
+\stopxmlsetups
+
+\startxmlsetups xml:step:cells
+ \cells {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}}
+\stopxmlsetups
+
+\startxmlsetups xml:step:texts
+ \texts {\xmltext{#1}{/top}} {\xmltext{#1}{/bot}}
+\stopxmlsetups
+
+\startxmlsetups xml:step:stepcell
+ \cells {\xmltext{#1}{/topcell}} {\xmltext{#1}{/botcell}}
+ \texts {\xmltext{#1}{/toptext}} {\xmltext{#1}{/bottext}}
+\stopxmlsetups
+
+\startxmlsetups xml:step:cell
+ \cell {\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:step:text
+ \text {\xmlflush{#1}}
+\stopxmlsetups
+
+\protect
+
+\continueifinputfile{m-steps.mkvi}
+
+\starttext
+
+\startbuffer
+<stepchart>
+ <cell> some cell </cell>
+ <text> some text </text>
+ <cell> some cell </cell>
+ <text> some text </text>
+ <cell> some cell </cell>
+</stepchart>
+\stopbuffer
+
+\typebuffer \processxmlbuffer
+
+
+\startbuffer
+<steptable>
+ <cell> some cell </cell>
+ <text> some text </text>
+ <cell> some cell </cell>
+ <text> some text </text>
+ <cell> some cell </cell>
+</steptable>
+\stopbuffer
+
+\typebuffer \processxmlbuffer
+
+\page
+
+\startSTEPchart
+ \cells {A} {B}
+ \cells {one} {five} \texts{$+2$}{$-2$}
+ \cells {two} {four} \texts{$+3$}{$-3$}
+ \cells {three} {three} \texts{$+4$}{$-4$}
+ \cells {four} {two} \texts{$+5$}{$-5$}
+ \cells {five} {one}
+\stopSTEPchart
+
+\startSTEPtable
+ \cell {one} \textset{$x$} {=}{$a+b+c$}
+ \cell {two} \textset{$c+d$}{=}{$y$}
+ \cell {three}
+\stopSTEPtable
+
+
+\page
+
+\startbuffer
+<stepchart>
+ <cells> <top> some text </top> <bot> some text </bot> </cells>
+ <texts> <top> text </top> <bot> text </bot> </texts>
+ <cells> <top> some text </top> <bot> some text </bot> </cells>
+</stepchart>
+\stopbuffer
+
+\processxmlbuffer
+
+\startbuffer
+<stepchart>
+ <cell> some text </cell>
+ <texts> <top> text </top> <bot> text </bot> </texts>
+ <cell> some text </cell>
+</stepchart>
+\stopbuffer
+
+\processxmlbuffer
+
+\page
+
+\startSTEPchart[second]
+ \startSTEPcell
+ \topcell {A}
+ \botcell {B}
+ \startSTEPcell
+ \topcell {one}
+ \botcell {five}
+ \toptext {$+2$}
+ \bottext {$-2$}
+ \stopSTEPcell
+ \startSTEPcell
+ \topcell {two}
+ \botcell {four}
+ \toptext {$+3$}
+ \bottext {$-3$}
+ \stopSTEPcell
+ \startSTEPcell
+ \topcell {three}
+ \botcell {three}
+ \toptext {$+4$}
+ \bottext {$-4$}
+ \stopSTEPcell
+ \startSTEPcell
+ \topcell {four}
+ \botcell {two}
+ \toptext {$+5$}
+ \bottext {$-5$}
+ \stopSTEPcell
+ \startSTEPcell
+ \topcell {five}
+ \botcell {one}
+ \stopSTEPcell
+\stopSTEPchart
+
+\STEPchart[first][alternative=horizontal]
+\STEPchart[first][alternative=vertical]
+
+\page
+
+\STEPchart[second][alternative=horizontal]
+\STEPchart[second][alternative=vertical]
+
+\page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-subsub.mkiv b/tex/context/modules/mkiv/m-subsub.mkiv
new file mode 100644
index 000000000..88be11680
--- /dev/null
+++ b/tex/context/modules/mkiv/m-subsub.mkiv
@@ -0,0 +1,76 @@
+%D \module
+%D [ file=m-subsub,
+%D version=2000.12.14,
+%D title=\CONTEXT\ Private Modules,
+%D subtitle=More Section Levels,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. This module is not public.
+
+\unprotect
+
+\definesection[\s!section-8]
+\definesection[\s!section-9]
+\definesection[\s!section-10]
+\definesection[\s!section-11]
+\definesection[\s!section-12]
+
+\definehead
+ [\v!subsubsubsubsubsection]
+ [\c!section=\s!section-8,
+ \c!default=\v!subsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsection]
+ [\c!section=\s!section-9,
+ \c!default=\v!subsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsection]
+ [\c!section=\s!section-10,
+ \c!default=\v!subsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsection]
+ [\c!section=\s!section-11,
+ \c!default=\v!subsubsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubsection]
+ [\c!section=\s!section-12,
+ \c!default=\v!subsubsubsubsubsubsubsubsection]
+
+\definehead
+ [\v!subsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\definehead
+ [\v!subsubsubsubsubsubsubsubsubsubject]
+ [\c!coupling=\v!subsubsubsubsubsubsubsubsubsection,
+ \c!default=\v!subsubsubsubsubsubsubsubsubsection,
+ \c!incrementnumber=\v!no]
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-timing.mkiv b/tex/context/modules/mkiv/m-timing.mkiv
new file mode 100644
index 000000000..5502768f6
--- /dev/null
+++ b/tex/context/modules/mkiv/m-timing.mkiv
@@ -0,0 +1,102 @@
+%D \module
+%D [ file=m-timing,
+%D version=2007.12.23,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Timing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\ifdefined\ShowNamedUsage \endinput \fi
+
+%D Written at the end of 2007, this module is dedicated to Taco. Reaching this
+%D point in \LUATEX\ was a non trivial effort. By visualizing a bit what happens
+%D when pages come out of \LUATEX, you may get an idea what is involved. It took
+%D much time an dedication to reach this point in the development. Add to that
+%D those daily Skype intense discussion, testing and debugging moments. Time flies
+%D but progress is impressive. The motto of this module could be: what you see
+%D is what you get. An there is much more to come \unknown.
+
+% \usemodule[timing]
+% \setupcolors[state=start]
+% \starttext
+% \dorecurse{200}{\input tufte \par} \ShowUsage{}
+% \stoptext
+
+\definecolor[usage:line] [darkred]
+\definecolor[usage:time] [darkblue]
+\definecolor[usage:frame][darkgray]
+
+\ctxloadluafile{trac-tim}{}
+
+\startluacode
+local progress = moduledata.progress
+
+function progress.show(filename,parameters,nodes,other)
+ for n, name in pairs(parameters or progress.parameters()) do
+ context.ShowNamedUsage(filename or progress.defaultfilename,name,other or "")
+ end
+ for n, name in pairs(nodes or progress.nodes(filename)) do
+ context.ShowNamedUsage(filename or progress.defaultfilename,name,other or "")
+ end
+end
+\stopluacode
+
+% \everyfirstshipout
+
+\startnotmode[no-timing]
+ \appendtoks\ctxlua{moduledata.progress.store()}\to\everystarttext
+ \appendtoks\ctxlua{moduledata.progress.store()}\to\everyshipout
+ \ctxlua{luatex.registerstopactions(function() moduledata.progress.save() end)}
+\stopnotmode
+
+\unexpanded\def\ShowNamedUsage#1#2#3%
+ {\setbox\scratchbox\vbox\bgroup
+ \startMPcode
+ begingroup ; save p, q, b, h, w ;
+ path p, q, b ; numeric h, w ;
+ p := \cldcontext{moduledata.progress.path("#1","#2")} ;
+ % p := p shifted -llcorner p ;
+ if bbwidth(p) > 0 :
+ h := 100 ; w := 2 * h ;
+ w := \the\textwidth-3pt ; % correct for pen
+ p := p xstretched w ;
+ b := boundingbox (llcorner p -- llcorner p shifted (w,h)) ;
+ pickup pencircle scaled 3pt ; linecap := butt ;
+ draw b withcolor \MPcolor{usage:frame} ;
+ draw p withcolor \MPcolor{usage:line} ;
+ if ("#3" <> "") and ("#3" <> "#2") :
+ q := \cldcontext{moduledata.progress.path("#1","#3")} ;
+ % q := q shifted -llcorner q ;
+ if bbwidth(q) > 1 :
+ q := q xstretched w ;
+ pickup pencircle scaled 1.5pt ; linecap := butt ;
+ draw q withcolor \MPcolor{usage:time} ;
+ fi ;
+ fi ;
+ fi ;
+ endgroup ;
+ \stopMPcode
+ \egroup
+ \scratchdimen\wd\scratchbox
+ \ifdim\scratchdimen>\zeropoint
+ \startlinecorrection
+ \box\scratchbox \endgraf
+ \hbox to \scratchdimen{\tttf\strut\detokenize{#2}\hss
+ min:\cldcontext{moduledata.progress.bot("#1","\detokenize{#2}")}, %
+ max:\cldcontext{moduledata.progress.top("#1","\detokenize{#2}")}, %
+ pages:\cldcontext{moduledata.progress.pages("#1")}%
+ }%
+ \stoplinecorrection
+ \fi}
+
+\unexpanded\def\LoadUsage #1{\ctxlua{moduledata.progress.convert("#1")}}
+\unexpanded\def\ShowUsage #1{\ctxlua{moduledata.progress.show("#1",nil,nil,"elapsed_time")}}
+\unexpanded\def\ShowMemoryUsage#1{\ctxlua{moduledata.progress.show("#1",nil,{}, "elapsed_time")}}
+\unexpanded\def\ShowNodeUsage #1{\ctxlua{moduledata.progress.show("#1",{},nil, "elapsed_time")}}
+
+\endinput
diff --git a/tex/context/modules/mkiv/m-trackers.mkiv b/tex/context/modules/mkiv/m-trackers.mkiv
new file mode 100644
index 000000000..95c34b16f
--- /dev/null
+++ b/tex/context/modules/mkiv/m-trackers.mkiv
@@ -0,0 +1,3 @@
+\starttext
+ \showtrackers
+\stoptext
diff --git a/tex/context/modules/mkiv/m-translate.mkiv b/tex/context/modules/mkiv/m-translate.mkiv
new file mode 100644
index 000000000..2e6cbe950
--- /dev/null
+++ b/tex/context/modules/mkiv/m-translate.mkiv
@@ -0,0 +1,127 @@
+%D \module
+%D [ file=m-translate,
+%D version=2008.10.09,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Translations,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D We can make this module more clever (wildcards and such) but since
+%D it's only a demo we stick to the simple case for now. After all, it's
+%D better to fix your source.
+
+\startluacode
+ local translators = { }
+
+ moduledata.translators = translators
+
+ local compiled, list = nil, nil
+
+ -- function translators.register(from,to)
+ -- local l = lpeg.P(from)/to
+ -- if not list then
+ -- list = l
+ -- else
+ -- list = list + l
+ -- end
+ -- compiled = nil
+ -- end
+ --
+ -- function translators.translate(s)
+ -- if list then
+ -- if not compiled then
+ -- compiled = lpeg.Cs((list + lpeg.P(1))^0)
+ -- end
+ -- return compiled:match(s)
+ -- else
+ -- return s
+ -- end
+ -- end
+
+ -- local function prepare()
+
+ function translators.register(from,to)
+ if not list then
+ list = { [from] = to }
+ else
+ list[from] = to
+ end
+ compiled = nil
+ end
+
+ function translators.translate(s)
+ if list then
+ if not compiled then
+ local tree = lpeg.utfchartabletopattern(list)
+ compiled = lpeg.Cs((tree/list + lpeg.patterns.utf8character)^0 * lpeg.P(-1)) -- the P(1) is needed in order to accept non utf
+ end
+ return compiled:match(s)
+ else
+ return s
+ end
+ end
+
+ local textlineactions = resolvers.openers.helpers.textlineactions
+
+ utilities.sequencers.appendaction(textlineactions,"after","moduledata.translators.translate")
+
+ function translators.enable()
+ utilities.sequencers.enableaction(textlineactions,"moduledata.translators.translate")
+ end
+
+ function translators.disable()
+ utilities.sequencers.disableaction(textlineactions,"moduledata.translators.translate")
+ end
+
+ function translators.reset(s)
+ translators.enable()
+ list, compiled = nil, nil
+ end
+
+ translators.disable()
+\stopluacode
+
+\unprotect
+
+\unexpanded\def\translateinput
+ {\dodoubleargument\module_translate_input}
+
+\def\module_translate_input[#1][#2]%
+ {\ctxlua{moduledata.translators.register(\!!bs#1\!!es,\!!bs#2\!!es)}}
+
+\unexpanded\def\resetinputtranslation
+ {\ctxlua{moduledata.translators.reset()}}
+
+\unexpanded\def\enableinputtranslation
+ {\ctxlua{moduledata.translators.enable()}}
+
+\unexpanded\def\disableinputtranslation
+ {\ctxlua{moduledata.translators.disable()}}
+
+\unexpanded\def\readtranslatedfile#1%
+ {\enableinputtranslation
+ \readfile{#1}\donothing\donothing
+ \disableinputtranslation}
+
+\protect
+
+\continueifinputfile{m-translate.mkiv}
+
+\starttext
+
+ \translateinput[Moica][Mojca]
+ % \translateinput[Idris][Idris (aka ادريس)]
+ \translateinput[Idris][Idris (aka <something arabic here>)]
+
+ \enableinputtranslation
+
+ Well, it's not that hard to satisfy Idris' and Moicas \TEX\ needs.
+
+ \readtranslatedfile{tufte}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/m-units.mkiv b/tex/context/modules/mkiv/m-units.mkiv
new file mode 100644
index 000000000..b0db8d548
--- /dev/null
+++ b/tex/context/modules/mkiv/m-units.mkiv
@@ -0,0 +1,912 @@
+%D \module
+%D [ file=m-units,
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Scientific Units,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Best use the built in unit handle!
+
+%D Scientific units can be typeset in math mode pretty well,
+%D but occasionally one has to take care of spacing.
+%D Furthermore, entering these units is not that natural as
+%D wanted. Therefore this module presents a more natural way of
+%D doing things, like:
+%D
+%D \starttyping
+%D 1.23 \Cubic \Meter \Per \Second
+%D \stoptyping
+%D
+%D This example shows that we use the order in which we say
+%D things, instead of typeset things. There is a separate
+%D manual for this module.
+
+%D Message number~1 deals with overruling the \type {\Degrees}
+%D macro defined in the core modules. Let's say that this is
+%D an upward compatibility issue.
+
+\startmessages dutch library: units
+ title: eenheden
+ 1: gebruik \string\Degrees\space\string\Celsius\space in plaats van \string\Celsius !
+\stopmessages
+
+\startmessages english library: units
+ title: units
+ 1: use \string\Degrees\space\string\Celsius\space instead of \string\Celsius !
+\stopmessages
+
+\startmessages german library: units
+ title: Einheiten
+ 1: Verwende \string\Degrees\space\string\Celsius\space statt \string\Celsius !
+\stopmessages
+
+\startmessages italian library: units
+ title: unita
+ 1: usare \string\Degrees\space\string\Celsius\space invece di \string\Celsius !
+\stopmessages
+
+\startmessages norwegian library: units
+ title: enheter
+ 1: bruk \string\Degrees\space\string\Celsius\space istedenfor \string\Celsius !
+\stopmessages
+
+\startmessages romanian library: units
+ title: unitati
+ 1: folositi \string\Degrees\space\string\Celsius\space in locul \string\Celsius !
+\stopmessages
+
+\startmessages french library: units
+ title: unitas
+ 1: utilisez \string\Degrees\space\string\Celsius\space A la place de \string\Celsius !
+\stopmessages
+
+\registerctxluafile{x-mathml}{}
+
+\unprotect
+
+\writestatus{\m!units}{The units module is obsolete because functionality is built into the core.}
+
+\let\unit\undefined
+
+\definesynonyms
+ [\v!unit]
+ [\v!units]
+ [\unitmeaning]
+
+\setupsynonyms
+ [\v!unit]
+ [\c!synonymcommand=\dimension]
+
+\startmodule[units]
+
+%D This runtime loadable module implements a way of defining
+%D units. The core macro is \type {\dimension}, a rather clever
+%D one that is able to cooperate with some other dimension
+%D related macros. As said, this module enables user to enter:
+%D
+%D \starttyping
+%D some 10 \Square \Meter \Per \Second or more
+%D \stoptyping
+%D
+%D The units itself are implemented as synonyms.
+%D
+%D \starttyping
+%D \definesynonyms [unit] [units] [\unitmeaning]
+%D \setupsynonyms [unit] [textstyle=\dimension]
+%D \stoptyping
+%D
+%D This definition means that we can ask for the meaning of a
+%D unit using \type {\unitmeaning} and get a list of used
+%D units by saying \type {\placelistofunits}
+%D
+%D We have to use the command \type {\unitmeaning} instead
+%D of \type {\meaning}, simply because the latter is a \TEX\
+%D primitive we don't want to loose. We use the label text
+%D mechanism for translations.
+
+%D \macros
+%D {dimension}
+%D
+%D The core of this module is the low level macro \type
+%D {\dimension}. Before presenting this macro, it's best to
+%D look at some applications, because it's supposed to show
+%D some intelligence that can beter be understood from the
+%D context.
+%D
+%D The next useless examples show some of the cases we want
+%D to handle in a proper way.
+%D
+%D \starttyping
+%D ... 10 \Square \Meter \Per \Volt \
+%D ... 10 \Square \Meter \Volt \
+%D ... 10 \Meter \Volt \
+%D ... 10 \Milli \Square \Meter \Per \Volt \
+%D ... 10 \Square \Milli \Meter \Per \Volt \
+%D ... 10 \Meter \Times \Meter \
+%D ... 10 \Square \Meter \Times \Meter \
+%D ... 10 \Square \Milli \Meter \Times \Meter \
+%D \stoptyping
+
+%D \macros
+%D {mathematicstypeface, dimensiontypeface,
+%D dimensionhalfspace, dimensionbackspace}
+%D
+%D There are some low level constants, that can be changed
+%D when needed. Some day I will write a decent setup command.
+
+\def\mathematicstypeface{\rm}
+\def\dimensiontypeface {\tf}
+
+\def\dimensionhalfspace {\ifmmode\,\else\hskip+.1em\relax\fi}
+\def\dimensionbackspace {\ifmmode\!\else\hskip-.1em\relax\fi}
+
+%D \macros
+%D {smashdimensionpower}
+%D
+%D Sometimes the baseline distance is not enough to provide
+%D for superscripts, so we smash their height by default.
+
+\newif\ifsmashdimensionpower \smashdimensionpowertrue
+
+%D The dimension mechanism uses a lot of signals to keep
+%D track if the current state.
+
+\newsignal\dimensionsignal
+\newsignal\dimensionpowersignal
+\newsignal\dimensionmidfixsignal
+\newsignal\dimensionaddfixsignal
+
+\let\thedimensionprefix = \empty
+\let\thedimensionpower = \empty
+
+%D \macros
+%D {spaceddimensions,textdimensions}
+%D
+%D The actual definition of \type {\dimension} overruled the
+%D one in the core modules. The boolean can be used to
+%D force spacing between units. The rather ugly test prevents
+%D problems with nested dimensions.
+
+\newif\ifspaceddimensions \spaceddimensionsfalse % user switch
+\newif\iftextdimensions \textdimensionsfalse % user switch
+
+%D You can see the consequence of forcing text dimensions
+%D when you compare the following code:
+%D
+%D \starttyping
+%D {\rm test \Square \Meter \Per \Second\ ziezo\Degrees} \par
+%D {\ss test \Square \Meter \Per \Second\ ziezo} \par
+%D {\tt test \Square \Meter \Per \Second\ ziezo}
+%D
+%D \textdimensionstrue
+%D
+%D {\rm test \Square \Meter \Per \Second\ ziezo} \par
+%D {\ss test \Square \Meter \Per \Second\ ziezo} \par
+%D {\tt test \Square \Meter \Per \Second\ ziezo}
+%D \stoptyping
+
+\newif\ifnesteddimension \nesteddimensionfalse % local switch
+
+\def\dodimensionpower#1%
+ {\iftextdimensions\expandafter\high\else\expandafter\normalsuperscript\fi{#1}}
+
+\def\ustartmathmode {\iftextdimensions\else\expandafter\startmathmode \fi}
+\def\ustopmathmode {\iftextdimensions\else\expandafter\stopmathmode \fi}
+\def\umathematicstypeface{\iftextdimensions\else\expandafter\mathematicstypeface\fi}
+
+%D In forced text mode, we ignore spacing in monospaced fonts.
+
+\def\udimensionhalfspace {\dodimensionspace\dimensionhalfspace}
+\def\udimensionbackspace {\dodimensionspace\dimensionbackspace}
+
+\def\dodimensionspace
+ {\iftextdimensions
+ \begingroup
+ \setbox0\hbox{i}%
+ \setbox2\hbox{m}%
+ \ifdim\wd0=\wd2
+ \endgroup
+ \@EAEAEA\gobbleoneargument
+ \else
+ \endgroup
+ \fi
+ \fi}
+
+\unexpanded\def\dimension#1%
+ {\begingroup
+ \global\let\savedthedimensionprefix\thedimensionprefix
+ \global\let\savedthedimensionpower\thedimensionpower
+ \unexpanded\def\dimension##1{\global\nesteddimensiontrue}%
+ \let\dimensionprefix\dimension
+ \let\dimensionmidfix\dimension
+ \let\dimensionsuffix\dimension
+ \let\dimensionpower \dimension
+ \global\nesteddimensionfalse
+ \setbox\scratchbox\hbox{\ustartmathmode#1\ustopmathmode}% pre-roll
+ \global\let\thedimensionprefix\savedthedimensionprefix
+ \global\let\thedimensionpower \savedthedimensionpower
+ \endgroup
+ \ifnesteddimension#1\else\dodimension{#1}\fi}
+
+\def\dodimension#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\zeropoint\relax
+ \ifmmode
+ \udimensionhalfspace
+ \udimensionhalfspace
+ \fi
+ \ustartmathmode\dimensiontypeface
+ \else
+ \ustartmathmode\dimensiontypeface
+ \ifspaceddimensions
+ \ifdim\scratchdimen=\dimensionsignal\relax
+ \udimensionhalfspace
+ \else\ifdim\scratchdimen=\dimensionpowersignal\relax
+ \udimensionhalfspace
+ \fi
+ \fi
+ \fi
+ \fi
+ \umathematicstypeface\thedimensionprefix#1%
+ \ifx\thedimensionpower\empty
+ \else\ifsmashdimensionpower
+ \setbox\scratchbox=\hbox
+ {\iftextdimensions
+ \tx\thedimensionpower
+ \else
+ $\scriptstyle\thedimensionpower$%
+ \fi}%
+ \ht\scratchbox=\zeropoint
+ \dodimensionpower{\box\scratchbox}%
+ \else
+ \dodimensionpower{\thedimensionpower}%
+ \fi\fi
+ \ustopmathmode
+ % otherwise nobreak before space in 2 \Milli \Meter\ blabla
+ \doifnotmode{atpragma}{\nobreak}% this was always \nobreak
+ % only test this at pragma
+ \ifx\thedimensionpower\empty
+ \hskip\dimensionsignal
+ \else
+ \hskip\dimensionpowersignal
+ \fi
+ \global\let\thedimensionprefix\empty
+ \global\let\thedimensionpower\empty}
+
+%D \macros
+%D {dontbreakdimension,
+%D dimensionprefix, dimensionaddfix,
+%D dimensionnopfix, dimensionmidfix,
+%D dimensionpower}
+%D
+%D Here are some auxilliary macros.
+
+\def\dontbreakdimension
+ {\scratchdimen\lastskip
+ \unskip
+ \nobreak
+ \hskip\scratchdimen
+ \nobreak}
+
+\def\dimensionprefix#1%
+ {\gdef\thedimensionprefix{#1}}
+
+\def\dimensionaddfix#1%
+ {\unskip
+ %\mathematics{\umathematicstypeface#1}%
+ \ustartmathmode\umathematicstypeface#1\ustopmathmode
+ \nobreak
+ \hskip\dimensionaddfixsignal}
+
+\def\dimensionnopfix#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\dimensionpowersignal\relax
+ \ustartmathmode
+ \else
+ \ustartmathmode
+ \udimensionhalfspace
+ \nobreak
+ \fi
+ \umathematicstypeface#1%
+ \ustopmathmode
+ \nobreak
+ \hskip\dimensionsignal}
+
+\def\dimensionmidfix#1%
+ {\dontbreakdimension
+ \ifdim\scratchdimen=\dimensionpowersignal\relax
+ \ustartmathmode
+ \udimensionbackspace
+ \nobreak
+ \else
+ \ustartmathmode
+ \fi
+ \umathematicstypeface#1%
+ \ustopmathmode
+ \nobreak
+ \hskip\dimensionmidfixsignal}
+
+\def\dimensionpower#1%
+ {\gdef\thedimensionpower{#1}}
+
+%D \macros
+%D {SIunits, noSI, doSI}
+%D
+%D Some low level unit switching macros:
+
+\newif\ifSIunits \SIunitstrue
+
+\def\noSI#1{\begingroup\SIunitsfalse#1\endgroup}
+\def\doSI#1{\begingroup\SIunitstrue #1\endgroup}
+
+%D \macros
+%D {Degrees}
+%D
+%D We can fake the degrees symbol with:
+
+\def\Degrees{\dimensionaddfix{\mathematics{\normalsuperscript\circ}}}
+
+%D \macros
+%D {Unit, NoUnit}
+%D
+%D When a dimension has no leading number, we can use \type
+%D {\Unit}, and when no unit is appended, \type {\NoUnit} is
+%D to be used, just to prevent the prefix migrating to the
+%D next occasion.
+
+\def\Unit {\hskip\dimensionsignal}
+\def\NoUnit {\dimension{}}
+
+%D The mechanism described at the top of this module, depends
+%D on several dimensional components, like prefixes:
+
+\def\Atto {\dimensionprefix{a}}
+\def\Femto {\dimensionprefix{f}}
+\def\Pico {\dimensionprefix{p}}
+\def\Nano {\dimensionprefix{n}}
+\def\Micro {\dimensionprefix{\iftextdimensions u\else\mu\fi}}
+\def\Milli {\dimensionprefix{m}}
+\def\Centi {\dimensionprefix{c}}
+\def\Deci {\dimensionprefix{d}} % 10^{01}
+\def\Hecto {\dimensionprefix{h}} % 10^{02}
+\def\Kilo {\dimensionprefix{k}} % 10^{03}
+\def\Mega {\dimensionprefix{M}} % 10^{06}
+\def\Giga {\dimensionprefix{G}} % 10^{09}
+\def\Tera {\dimensionprefix{T}} % 10^{12}
+\def\Peta {\dimensionprefix{P}} % 10^{15}
+\def\Exa {\dimensionprefix{E}} % 10^{18}
+
+%def\Terra {\dimensionprefix{T}} % for old times sake
+
+\def\Kibi {\dimensionprefix{ki}} % 2^{10}
+\def\Mebi {\dimensionprefix{Mi}} % 2^{20}
+\def\Gibi {\dimensionprefix{Gi}} % 2^{30}
+\def\Tebi {\dimensionprefix{Ti}} % 2^{40}
+\def\Pebi {\dimensionprefix{Pi}} % 2^{50}
+
+%D and binary prefixes:
+
+\def\Kibi {\dimensionprefix{Ki}}
+\def\Mebi {\dimensionprefix{Mi}}
+\def\Gibi {\dimensionprefix{Gi}}
+\def\Tebi {\dimensionprefix{Ti}}
+\def\Pebi {\dimensionprefix{Pi}}
+\def\Exbi {\dimensionprefix{Ei}}
+\def\Zebi {\dimensionprefix{Zi}}
+\def\Yobi {\dimensionprefix{Yi}}
+
+%D and operators:
+
+\def\Times {\dimensionnopfix{\iftextdimensions.\else\cdot\fi}}
+\def\Solidus {\dimensionmidfix{/}}
+\def\Per {\dimensionmidfix{/}}
+\def\OutOf {\dimensionnopfix{:}}
+
+%D and suffixes:
+
+\def\Linear {\dimensionpower{1}}
+\def\Square {\dimensionpower{2}}
+\def\Cubic {\dimensionpower{3}}
+
+\def\Inverse {\dimensionpower{-1}}
+\def\ILinear {\dimensionpower{-1}}
+\def\ISquare {\dimensionpower{-2}}
+\def\ICubic {\dimensionpower{-3}}
+
+%D Apart from these components, the units themselves are
+%D defined using the synonym mechanism. First we define some
+%D length and volume related units.
+
+\getvalue{\v!unit} [Meter] {m} {meter}
+\getvalue{\v!unit} [pMeter] {\Pico \Meter} {picometer}
+\getvalue{\v!unit} [nMeter] {\Nano \Meter} {nanometer}
+\getvalue{\v!unit} [uMeter] {\Micro \Meter} {micrometer}
+\getvalue{\v!unit} [mMeter] {\Milli \Meter} {millimeter}
+\getvalue{\v!unit} [cMeter] {\Centi \Meter} {centimeter}
+\getvalue{\v!unit} [dMeter] {\Deci \Meter} {decimeter}
+\getvalue{\v!unit} [hMeter] {\Hecto \Meter} {hectometer}
+\getvalue{\v!unit} [kMeter] {\Kilo \Meter} {kilometer}
+
+%D After some discussion on the \CONTEXT\ mailing list in
+%D february 2002 it was decided to go from L to l for liters
+%D (Karel Wesselings alternative: \mathematics{\ell}).
+
+\getvalue{\v!unit} [Liter] {l} {liter}
+\getvalue{\v!unit} [mLiter] {\Milli \Liter} {milliliter}
+\getvalue{\v!unit} [cLiter] {\Centi \Liter} {centiliter}
+\getvalue{\v!unit} [dLiter] {\Deci \Liter} {deciliter}
+
+%D Next we define time related units (\type {\ifSI} still dutch only).
+
+\getvalue{\v!unit} [Sec] {s} {\labeltext{u:sec}}
+\getvalue{\v!unit} [fSec] {\Femto \Sec} {\labeltext{u:fsec}}
+\getvalue{\v!unit} [pSec] {\Pico \Sec} {\labeltext{u:psec}}
+\getvalue{\v!unit} [nSec] {\Nano \Sec} {\labeltext{u:nsec}}
+\getvalue{\v!unit} [uSec] {\Micro \Sec} {\labeltext{u:usec}}
+\getvalue{\v!unit} [mSec] {\Milli \Sec} {\labeltext{u:msec}}
+\getvalue{\v!unit} [Year] {\ifSIunits a \else j\fi} {\labeltext{u:year}}
+\getvalue{\v!unit} [Month] {m} {\labeltext{u:month}}
+\getvalue{\v!unit} [Week] {w} {\labeltext{u:week}}
+\getvalue{\v!unit} [Day] {d} {\labeltext{u:day}}
+\getvalue{\v!unit} [Hour] {\ifSIunits h \else u\fi} {\labeltext{u:hour}}
+\getvalue{\v!unit} [Min] {min} {\labeltext{u:min}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:sec=seconde,
+ u:psec=picoseconde,
+ u:fsec=femtoseconde,
+ u:nsec=nanoseconde,
+ u:usec=microseconde,
+ u:msec=milliseconde,
+ u:year=jaar,
+ u:month=maand,
+ u:week=week,
+ u:day=dag,
+ u:hour=uur,
+ u:min=minuten]
+
+\setuplabeltext
+ [\s!en]
+ [u:sec=second,
+ u:fsec=femtosecond,
+ u:psec=picosecond,
+ u:nsec=nanosecond,
+ u:usec=microsecond,
+ u:msec=millisecond,
+ u:year=year,
+ u:month=month,
+ u:week=week,
+ u:day=day,
+ u:hour=hour,
+ u:min=minutes]
+
+\setuplabeltext
+ [\s!de]
+ [u:sec=Sekunde,
+ u:fsec=Femtosekunde,
+ u:psec=Picosekunde,
+ u:nsec=Nanosekunde,
+ u:usec=Microsekunde,
+ u:msec=Millisekunde,
+ u:year=Jahr,
+ u:month=Monat,
+ u:week=Woche,
+ u:day=Tag,
+ u:hour=Stunde,
+ u:min=Minuten]
+
+\setuplabeltext
+ [\s!hr]
+ [u:sec=sekunda,
+ u:fsec=femtosekunda,
+ u:psec=pikosekunda,
+ u:nsec=nanosekunda,
+ u:usec=mikrosekunda,
+ u:msec=milisekunda,
+ u:year=godina,
+ u:month=mjesec,
+ u:week=tjedan,
+ u:day=dan,
+ u:hour=sat,
+ u:min=minuta]
+
+\setuplabeltext
+ [\s!it]
+ [u:sec=secondo,
+ u:fsec=femtosecondo,
+ u:psec=picosecondo,
+ u:nsec=nanosecondo,
+ u:usec=microsecondo,
+ u:msec=millisecondo,
+ u:year=anno,
+ u:month=mese,
+ u:week=settimana,
+ u:day=giorno,
+ u:hour=ora,
+ u:min=minuti]
+
+%D Then we define some angles.
+
+\getvalue{\v!unit} [Rad] {rad} {\labeltext{u:rad}}
+\getvalue{\v!unit} [Deg] {{\mathematics{\normalsuperscript\circ}}} {\labeltext{u:deg}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:rad=hoek radialen,
+ u:deg=hoek graden]
+
+\setuplabeltext
+ [\s!en]
+ [u:rad=angle radians,
+ u:deg=angle degrees]
+
+\setuplabeltext
+ [\s!de]
+ [u:rad=Bogenma\SS,
+ u:deg=Gradma\SS]
+
+\setuplabeltext
+ [\s!hr]
+ [u:rad=radijani,
+ u:deg=kutni stupnjevi]
+
+\setuplabeltext
+ [\s!it]
+ [u:rad=radianti,
+ u:deg=angoli sessagesimali]
+
+%D Rotation and frequency related units are defined by:
+
+\getvalue{\v!unit} [Hertz] {Hz} {Hertz}
+\getvalue{\v!unit} [kHertz] {\Kilo \Hertz} {kilo Hertz}
+\getvalue{\v!unit} [MHertz] {\Mega \Hertz} {mega Hertz}
+\getvalue{\v!unit} [GHertz] {\Giga \Hertz} {giga Hertz}
+\getvalue{\v!unit} [THertz] {\Tera \Hertz} {tera Hertz}
+\getvalue{\v!unit} [mHertz] {\Milli \Hertz} {milli Hertz}
+
+\getvalue{\v!unit} [RevPerSec] {RPS} {\labeltext{u:rps}}
+\getvalue{\v!unit} [RevPerMin] {RPM} {\labeltext{u:rpm}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:rps=omwentelingen per seconde,
+ u:rpm=omwentelingen per minuut]
+
+\setuplabeltext
+ [\s!en]
+ [u:rps=revolutions per second,
+ u:rpm=revolutions per minute]
+
+\setuplabeltext
+ [\s!de]
+ [u:rps=Umdrehungen pro Sekunde,
+ u:rpm=Umdrehungen pro Minute]
+
+\setuplabeltext
+ [\s!hr]
+ [u:rps=okretaji po sekundi,
+ u:rpm=okretaji po minuti]
+
+\setuplabeltext
+ [\s!it]
+ [u:rps=giri al secondo,
+ u:rpm=giri al minuto]
+
+%D Mass and force:
+
+\getvalue{\v!unit} [Gram] {g} {gram}
+\getvalue{\v!unit} [uGram] {\Micro \Gram} {microgram}
+\getvalue{\v!unit} [mGram] {\Milli \Gram} {milligram}
+\getvalue{\v!unit} [kGram] {\Kilo \Gram} {kilogram}
+\getvalue{\v!unit} [Atom] {u} {\labeltext{u:u}}
+
+\getvalue{\v!unit} [Newton] {N} {Newton}
+\getvalue{\v!unit} [kNewton] {\Kilo \Newton} {kilo Newton}
+
+\getvalue{\v!unit} [Pascal] {Pa} {Pascal}
+\getvalue{\v!unit} [mPascal] {\Milli \Pascal} {milli Pascal}
+\getvalue{\v!unit} [kPascal] {\Kilo \Pascal} {kilo Pascal}
+
+\setuplabeltext
+ [\s!nl]
+ [u:u=atomaire massa eenheid]
+
+\setuplabeltext
+ [\s!en]
+ [u:u=atom mass unit]
+
+\setuplabeltext
+ [\s!de]
+ [u:u=Atomare Masseneinheit]
+
+\setuplabeltext
+ [\s!hr]
+ [u:u=unificirana atomska jedinica mase]
+
+\setuplabeltext
+ [\s!it]
+ [u:u=unit\`a di massa atomica]
+
+%D Energy units comes in two alternatives:
+
+\getvalue{\v!unit} [Joule] {J} {Joule}
+\getvalue{\v!unit} [mJoule] {\Milli \Joule} {milli Joule}
+\getvalue{\v!unit} [kJoule] {\Kilo \Joule} {kilo Joule}
+\getvalue{\v!unit} [MJoule] {\Mega \Joule} {mega Joule}
+\getvalue{\v!unit} [GJoule] {\Giga \Joule} {giga Joule}
+
+\getvalue{\v!unit} [Watt] {W} {Watt}
+\getvalue{\v!unit} [mWatt] {\Milli \Watt} {milli Watt}
+\getvalue{\v!unit} [kWatt] {\Kilo \Watt} {kilo Watt}
+\getvalue{\v!unit} [MWatt] {\Mega \Watt} {mega Watt}
+\getvalue{\v!unit} [GWatt] {\Giga \Watt} {giga Watt}
+\getvalue{\v!unit} [TWatt] {\Tera \Watt} {tera Watt}
+
+%D Although Celsius is no longer permitted, we define it by
+%D saying:
+
+\getvalue{\v!unit} [Celsius] {C} {Celsius}
+\getvalue{\v!unit} [Kelvin] {K} {Kelvin}
+\getvalue{\v!unit} [Fahrenheit] {F} {Fahrenheit}
+
+%D Some chemic related units are:
+
+\getvalue{\v!unit} [Mol] {mol} {mol}
+\getvalue{\v!unit} [mMol] {\Milli \Mol} {millimol}
+\getvalue{\v!unit} [kMol] {\Kilo \Mol} {kilomol}
+\getvalue{\v!unit} [Molair] {M} {molair (\Mol \Per \Liter)}
+\getvalue{\v!unit} [Equivalent] {eq} {equivalent}
+\getvalue{\v!unit} [mEquivalent] {\Milli \Equivalent} {milli equivalent}
+
+%D There are quite a lot units related to electricity and
+%D magnetism:
+
+\getvalue{\v!unit} [Farad] {F} {Farad}
+\getvalue{\v!unit} [pFarad] {\Pico \Farad} {pico Farad}
+\getvalue{\v!unit} [nFarad] {\Nano \Farad} {nano Farad}
+\getvalue{\v!unit} [uFarad] {\Micro \Farad} {micro Farad}
+\getvalue{\v!unit} [mFarad] {\Milli \Farad} {milli Farad}
+
+\getvalue{\v!unit} [Ohm] {\Omega} {Ohm}
+\getvalue{\v!unit} [kOhm] {\Kilo \Ohm} {kilo Ohm}
+
+\getvalue{\v!unit} [Siemens] {S} {Siemens}
+
+\getvalue{\v!unit} [Ampere] {A} {Amp\`ere}
+\getvalue{\v!unit} [mAmpere] {\Milli \Ampere} {milli Amp\`ere}
+
+\getvalue{\v!unit} [Coulomb] {C} {Coulomb}
+
+\getvalue{\v!unit} [Volt] {V} {Volt}
+\getvalue{\v!unit} [mVolt] {\Milli \Volt} {milli Volt}
+\getvalue{\v!unit} [kVolt] {\Kilo \Volt} {kilo Volt}
+\getvalue{\v!unit} [eVolt] {eV} {electronvolt}
+\getvalue{\v!unit} [keVolt] {\Kilo \eVolt} {kilo electronvolt}
+\getvalue{\v!unit} [MeVolt] {\Mega \eVolt} {mega electronvolt}
+
+\getvalue{\v!unit} [Tesla] {T} {Tesla}
+
+\getvalue{\v!unit} [VoltAC] {V\normalsubscript{\xbox{ac}}} {\labeltext{u:vac}}
+\getvalue{\v!unit} [VoltDC] {V\normalsubscript{\xbox{dc}}} {\labeltext{u:vdc}}
+
+\setuplabeltext
+ [\s!nl]
+ [u:vac=wisselspanning,
+ u:vdc=gelijkspanning]
+
+\setuplabeltext
+ [\s!en]
+ [u:vac=alternating current,
+ u:vdc=direct current]
+
+\setuplabeltext
+ [\s!de]
+ [u:vac=Wechselspannung,
+ u:vdc=Gleichspannung]
+
+\setuplabeltext
+ [\s!hr]
+ [u:vac=izmjeni\ccaron ni napon,
+ u:vdc=istosmjerni napon]
+
+\setuplabeltext
+ [\s!it]
+ [u:vac=corrente alternata,
+ u:vdc=corrente continua]
+
+%D Network bandwidth is specified in Bits:
+
+\getvalue{\v!unit} [Bit] {bit} {\labeltext{u:bit}}
+\getvalue{\v!unit} [Baud] {Bd} {Baud (Bit/s)}
+
+%D Computer memory size is specified in Bytes:
+
+\getvalue{\v!unit} [Byte] {B} {\labeltext{u:byte}}
+\getvalue{\v!unit} [kByte] {\Kilo \Byte} {kilo Byte}
+\getvalue{\v!unit} [MByte] {\Mega \Byte} {mega Byte}
+\getvalue{\v!unit} [GByte] {\Giga \Byte} {giga Byte}
+\getvalue{\v!unit} [TByte] {\Tera \Byte} {tera Byte}
+
+\setuplabeltext
+ [\s!en]
+ [u:bit=Bit,
+ u:byte=Byte]
+
+\setuplabeltext
+ [\s!hr]
+ [u:bit=bit,
+ u:byte=bajt]
+
+%D Telecommunication call density is specified in Erlangs:
+
+\getvalue{\v!unit} [Erlang] {E} {Erlang}
+
+%D Some radiation related units:
+
+\getvalue{\v!unit} [Bequerel] {Bq} {Bequerel}
+\getvalue{\v!unit} [MBequerel] {\Mega \Bequerel} {Bequerel}
+\getvalue{\v!unit} [Sievert] {Sv} {Sievert}
+\getvalue{\v!unit} [mSievert] {\Milli \Sievert} {milli Sievert}
+
+%D Light:
+
+\getvalue{\v!unit} [Candela] {cd} {Candela}
+
+%D and some sound ones:
+
+\getvalue{\v!unit} [Bell] {B} {Bell}
+\getvalue{\v!unit} [dBell] {\Deci \Bell} {decibel}
+
+%D We also define some non||regular, sometimes even forbidden,
+%D units:
+
+\getvalue{\v!unit} [At] {at} {\labeltext{u:at}}
+\getvalue{\v!unit} [Atm] {atm} {\labeltext{u:atm}}
+\getvalue{\v!unit} [Bar] {bar} {bar (100 \Kilo \Pascal)}
+\getvalue{\v!unit} [EVolt] {eV} {electronvolt}
+\getvalue{\v!unit} [Foot] {ft} {\labeltext{u:ft}}
+\getvalue{\v!unit} [Inch] {inch} {\labeltext{u:inch}}
+\getvalue{\v!unit} [Cal] {cal} {\labeltext{u:cal}}
+\getvalue{\v!unit} [Force] {f} {\labeltext{u:f}}
+\getvalue{\v!unit} [kCal] {\Kilo \Cal} {\labeltext{u:kcal}}
+\getvalue{\v!unit} [Lux] {lux} {lux}
+
+
+\def\xPercent {\dimensionaddfix{\percent }}
+\def\xPromille{\dimensionaddfix{\promille}}
+
+\getvalue{\v!unit} [Percent] {\xPercent } {percent}
+\getvalue{\v!unit} [Permille] {\xPromille} {promille}
+\getvalue{\v!unit} [Promille] {\xPromille} {promille}
+
+%D Some more, thanks to Tobias:
+
+\getvalue{\v!unit} [Gray] {Gr} {Gray}
+\getvalue{\v!unit} [Weber] {Wb} {Weber}
+\getvalue{\v!unit} [Henry] {H} {Henry}
+\getvalue{\v!unit} [Sterant] {sr} {Sterant}
+\getvalue{\v!unit} [Angstrom] {\hbox{\Aring}} {\Aring ngstr\"om}
+\getvalue{\v!unit} [Gauss] {G} {Gauss}
+
+\setuplabeltext
+ [\s!nl]
+ [u:at=technische atmosfeer,
+ u:atm=fysische atmosfeer,
+ u:ft=voet,
+ u:cal=calorie,
+ u:f=kracht (force),
+ u:kcal=kilocalorie]
+
+\setuplabeltext
+ [\s!en]
+ [u:at=technical atmospheric pressure,
+ u:atm=physical atmospheric pressure,
+ u:ft=foot,
+ u:inch=inch,
+ u:cal=calory,
+ u:f=force,
+ u:kcal=kilocalory]
+
+\setuplabeltext
+ [\s!de]
+ [u:at=Technischer atmosph\"arischer Druck,
+ u:atm=physkalischer atmosph\"arischer Druck,
+ u:ft=Fu\SS,
+ u:cal=Kalorien,
+ u:f=Force,
+ u:kcal=Kilokalorien]
+
+\setuplabeltext
+ [\s!hr]
+ [u:at=tehni\ccaron ka atmosfera,
+ u:atm=standardna atmosfera,
+ u:ft=stopa,
+ u:inch=in\ccaron a,
+ u:cal=kalorija,
+ u:f=Force,
+ u:kcal=Kilokalorien]
+
+\setuplabeltext
+ [\s!it]
+ [u:at=pressione atmosferica tecnica,
+ u:atm=pressione atmosfera fisica,
+ u:ft=piede,
+ u:cal=caloria,
+ u:f=forza,
+ u:kcal=chilocaloria]
+
+%D Here are some old ones, still there for compatibility
+%D reasons. These will probably be obsolete in a few years.
+
+\def\MeterTwee {\Square \Meter}
+\def\mMeterTwee {\Square \Milli \Meter}
+\def\cMeterTwee {\Square \Centi \Meter}
+\def\dMeterTwee {\Square \Deci \Meter}
+\def\kMeterTwee {\Square \Kilo \Meter}
+
+\def\MeterDrie {\Cubic \Meter}
+\def\mMeterDrie {\Cubic \Milli \Meter}
+\def\cMeterDrie {\Kubic \Centi \Meter}
+\def\dMeterDrie {\Cubic \Deci \Meter}
+\def\kMeterDrie {\Cubic \Kilo \Meter}
+
+\def\LiterTwee {\Square \Liter}
+\def\SecTwee {\Square \Sec}
+\def\SecMinEen {\Inverse \Sec}
+
+%D To make ourselves happy, we define some dutch specific
+%D units:
+
+\startinterface dutch
+
+ \getvalue{\v!unit} [PaardenKracht] {pk} {paardenkracht}
+ \getvalue{\v!unit} [Duits] {D} {duits}
+ \getvalue{\v!unit} [Kwik] {Hg} {kwikkolom}
+ \getvalue{\v!unit} [Hectare] {ha} {hectare}
+ \getvalue{\v!unit} [kGramForce] {\Kilo \Gram \Force} {kilogramforce}
+ \getvalue{\v!unit} [kWattUur] {\Kilo \Watt \Uur} {kilowattuur}
+ \getvalue{\v!unit} [MeterKwik] {\Meter \Kwik} {meter kwikkolom}
+ \getvalue{\v!unit} [Waterkolom] {WK} {waterkolom}
+ \getvalue{\v!unit} [MeterWater] {\Meter \Waterkolom} {meter waterkolom}
+ \getvalue{\v!unit} [DrogeStof] {ds} {droge stof}
+ \getvalue{\v!unit} [Normaal] {N} {normaal}
+
+ \getvalue{\v!unit} [Ton] {t} {ton}
+ \getvalue{\v!unit} [kTon] {\Kilo \Ton} {kiloton}
+
+ \let \OmwPerSec \RevPerSec
+ \let \OmwPerMin \RevPerMin
+ \let \Graden \Deg
+ \let \PaardeKracht \PaardenKracht
+ \let \Atoom \Atom
+ \let \Heure \Hour
+ \let \Jaar \Year
+ \let \Maand \Month
+ \let \Dag \Day
+ \let \Uur \Hour
+
+\stopinterface
+
+%D Finally we define some equivalents. By using \type {\let}
+%D we can be sure that they don't end up double in the lists of
+%D units.
+
+\let \Second \Sec
+\let \Kubic \Cubic
+\let \IKubic \ICubic
+
+%D Option:
+
+% \def\Micro{\dimensionprefix{\iftextdimensions\mathematics\mu \else\mu \fi}}
+% \def\Times{\dimensionnopfix{\iftextdimensions\mathematics\cdot\else\cdot\fi}}
+
+\stopmodule
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/m-visual.mkiv b/tex/context/modules/mkiv/m-visual.mkiv
new file mode 100644
index 000000000..d50215966
--- /dev/null
+++ b/tex/context/modules/mkiv/m-visual.mkiv
@@ -0,0 +1,809 @@
+%D \module
+%D [ file=m-visual,
+%D version=2000.01.10,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Visualization and Faking,
+%D author={Hans Hagen \& Ton Otten},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D Much will probably be replaced by \LUA\ based solutions which is
+%D rather trivial and fun doing.
+
+%D This module collect a few more visual debugger features. I
+%D needed them for manuals and styles. The macros are documented
+%D in a my way document.
+
+\definecolor[fakerulecolor] [black]
+\definecolor[fakebaselinecolor] [green]
+\definecolor[fakeparindentcolor][blue]
+
+\newif\iffakebaseline \fakebaselinetrue
+
+\unexpanded\def\fakerule#1%
+ {\strut
+ \begingroup
+ \directcolored[fakerulecolor]%
+ \iffakebaseline
+ \vrule\s!height1.25ex\s!depth-.05ex\s!width#1%
+ \kern-#1%
+ \vrule\s!height-.05ex\s!depth .25ex\s!width#1%
+ \else
+ \vrule\s!height1.25ex\s!depth .25ex\s!width#1%
+ \fi
+ \endgroup
+ \allowbreak}
+
+\unexpanded\def\dorandomrecurse#1%
+ {\getrandomcount\scratchcounter{1}{#1}%
+ \dorecurse\scratchcounter}
+
+% can be used in hbox, so %'s are really needed
+
+\unexpanded\def\fakelines#1#2% min max / 3 10
+ {\fakeparindent
+ \scratchdimen\hsize
+ \ifindentation
+ \advance\scratchdimen -\parindent
+ \fi
+ \fakerule\scratchdimen\break
+ \getrandomcount\scratchcounter{\ifcase0#1 3\else#1\fi}{\ifcase0#2 10\else#2\fi}%
+ \dorecurse\scratchcounter{\fakerule\hsize}%
+ \getrandomdimen\scratchdimen{.25\hsize}\hsize
+ \fakerule\scratchdimen
+ \par} % indeed
+
+\unexpanded\def\fakewords
+ {\ifvmode\fakeparindent\fi\onlyfakewords}
+
+\definepalet
+ [fakerule]
+ [fr1c=darkred,
+ fr2c=darkgreen,
+ fr3c=darkblue,
+ fr4c=darkyellow,
+ fr5c=darkgray]
+
+\unexpanded\def\onlyfakewords#1#2% min max / 10 40
+ {\getrandomcount\scratchcounter{\ifcase0#1 10\else#1\fi}{\ifcase0#2 40\else#2\fi}%
+ \dofakewords\scratchcounter
+ } % no \par
+
+\unexpanded\def\fakenwords#1#2% words seed
+ {\fakeparindent
+ \getrandomseed\fakedwordseed
+ \setrandomseed{\ifcase0#2 #1\else#2\fi}%
+ \dofakewords{#1}%
+ \setrandomseed\fakedwordseed
+ } % no \par
+
+\def\dofakewords#1%
+ {\bgroup
+ \dorecurse{#1}
+ {\getrandomcount\scratchcounter{1}{5}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{.5em}{1.25em}%
+ \fakerule\scratchdimen}%
+ \space}%
+ \removeunwantedspaces
+ \egroup}
+
+\def\doshowfakewords#1%
+ {\bgroup
+ \setuppalet[fakerule]%
+ \definecolor[fakerulecolor]%
+ \dorecurse{#1}
+ {\getrandomcount\scratchcounter{1}{5}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{.5em}{1.25em}%
+ \color[fr\recurselevel c]{\fakerule\scratchdimen}}%
+ \space}%
+ \removeunwantedspaces
+ \egroup}
+
+\unexpanded\def\showfakewords
+ {\let\dofakewords\doshowfakewords}
+
+\unexpanded\def\fakeword
+ {\fakewords{1}{1}} % no \plusone
+
+\unexpanded\def\fakeparindent
+ {\noindent
+ \ifindentation
+ \ifx\dofakedroppedcaps\relax
+ {\fakeparindentcolor
+ \vrule
+ \s!height \strutheight % not longer .5ex
+ \s!depth \strutdepth % not longer 0pt
+ \s!width \parindent}%
+ \else
+ \dofakedroppedcaps \let\dofakedroppedcaps\relax
+ \fi
+% \else
+% \dontleavehmode
+ \fi}
+
+\let\dofakedroppedcaps\relax
+
+\unexpanded\def\fakedroppedcaps#1%
+ {\ifnum#1>0
+ \def\dofakedroppedcaps
+ {\setbox\scratchbox\hbox
+ {\setbox\scratchbox\hbox{W}%
+ \scratchdimen#1\lineheight
+ \advance\scratchdimen -\lineheight
+ \advance\scratchdimen \dp\strutbox
+ \vrule
+ \s!width#1\wd\scratchbox
+ \s!height\ht\scratchbox
+ \s!depth\scratchdimen}%
+ \ht\scratchbox\ht\strutbox
+ \dp\scratchbox\dp\strutbox
+ \hangindent\wd\scratchbox
+ \advance\hangindent .5em
+ \wd\scratchbox\hangindent
+ \hangafter-#1\noindent
+ \llap{\fakeparindentcolor\box\scratchbox}}%
+ \fi}
+
+\unexpanded\def\fakefigure
+ {\dodoubleempty\dofakefigure}
+
+\def\dofakefigure[#1][#2]#3#4#5#6% [] [] minwidth maxwidth minheight maxheight
+ {\getvalue{\e!place\v!figure}
+ [#1][#2]%
+ {\freezerandomseed
+ \let\endstrut\relax
+ \let\begstrut\relax
+ \doifelseinset{#1}{\v!left,\v!right}
+ {\fakewords{2}{4}}
+ {\fakewords{4}{10}}}%
+ {\doifinset{#1}{\v!left,\v!right}
+ {\dimen0=.75\dimen0
+ \ifdim\dimen0>.6\hsize \dimen0=.5\hsize\fi
+ \ifdim\dimen0<.3\hsize \dimen0=.3\hsize\fi}%
+ \framed
+ [\c!width=\dimen0,
+ \c!height=\dimen2,
+ \c!frame=\v!off,
+ \c!background=\v!color,
+ \c!backgroundcolor=fakeparindentcolor]
+ {\bf\white#1}}%
+ \defrostrandomseed}
+
+\unexpanded\def\fakeimage#1#2#3#4%
+ {\getrandomdimen{\dimen0}{#1}{#3}%
+ \getrandomdimen{\dimen2}{#2}{#4}%
+ \framed
+ [\c!width=\dimen0,
+ \c!height=\dimen2,
+ \c!frame=\v!off,
+ \c!background=\v!color,
+ \c!backgroundcolor=fakeparindentcolor]
+ {}}
+
+\unexpanded\def\fakeformula
+ {\dimen0\zeropoint
+ \getrandomcount\scratchcounter{3}{6}%
+ \dorecurse\scratchcounter
+ {\getrandomdimen\scratchdimen{0.5em}{1.5em}%
+ \mathord{\red\fakerule\scratchdimen}%
+ \ifnum\recurselevel<\scratchcounter+\fi
+ \advance\scratchdimen\dimen0}%
+ =\mathinner{\red\fakerule\scratchdimen}}
+
+\unexpanded\def\fakespacingformula
+ {\color[fakebaselinecolor]{\ruledbaseline}\fakeformula}
+
+%D test \type{\bodyfontgrid}\space test
+%D test \type{\emexgrid} \space test
+
+\unexpanded\def\smashedgrid
+ {\dosingleempty\dosmashedgrid}
+
+\def\dosmashedgrid[#1]%
+ {\hsmashed
+ {\setbox\scratchbox=\hbox
+ {\basegrid
+ [\c!nx=10,\c!ny=10,\c!dx=1,\c!dy=1,
+ \c!unit=\bodyfontsize,#1]}%
+ \hbox to \zeropoint
+ {\hss\lower.5\ht\scratchbox\box\scratchbox\hss}%
+ \hbox to \zeropoint
+ {\hss
+ \black\vrule\s!width6\linewidth\s!height3\linewidth\s!depth3\linewidth
+ \hss}}}
+
+\unexpanded\def\bodyfontgrid
+ {\hbox
+ {{\linewidth.1pt\yellow\smashedgrid[\c!nx=30,\c!ny=30,\c!scale=.3333]}%
+ {\linewidth.2pt\green \smashedgrid[\c!nx=20,\c!ny=20,\c!scale=.5]}%
+ {\linewidth.3pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!scale=1]}}}
+
+\unexpanded\def\emexgrid
+ {\hbox
+ {{\linewidth.15pt\green\smashedgrid[\c!nx=20,\c!ny=20,\c!unit=ex]}%
+ {\linewidth.15pt\red \smashedgrid[\c!nx=10,\c!ny=10,\c!unit=em]}}}
+
+%D For Mojca:
+
+\unexpanded\def\simplethesis
+ {\setupsystem[random=1234]
+ \title{\fakewords{3}{4}}
+ \placelist[chapter,section]
+ \dorecurse{6}
+ {\chapter{\fakewords{5}{10}}
+ \dorecurse{5}
+ {\section{\fakewords{2}{5}}
+ \dorecurse{2}
+ {\dorecurse{3}{\fakewords{100}{200}\endgraf}
+ \placefigure{\fakewords{8}{15}}{\fakeimage{5cm}{3cm}{10cm}{5cm}}
+ \dorecurse{2}{\fakewords{100}{200}\endgraf}}}}}
+
+%D Moved code:
+
+%D \module
+%D [ file=trac-vis, % was core-vis,
+%D version=1996.06.01,
+%D title=\CONTEXT\ Tracking Macros,
+%D subtitle=Visualization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module adds some more visualization cues to the ones
+%D supplied in the support module.
+%D
+%D %\everypar dual character, \the\everypar and \everypar=
+%D %\hrule cannot be grabbed in advance, switches mode
+%D %\vrule cannot be grabbed in advance, switches mode
+%D %
+%D %\indent only explicit ones
+%D %\noindent only explicit ones
+%D %\par only explicit ones
+%D
+%D %\leftskip only if explicit one
+%D %\rightskip only if explicit one
+
+\writestatus{loading}{ConTeXt Tracking Macros / Visualization}
+
+\unprotect
+
+%D \macros
+%D {indent, noindent, par}
+%D
+%D \TeX\ acts upon paragraphs. In mosts documents paragraphs
+%D are separated by empty lines, which internally are handled as
+%D \type{\par}. Paragraphs can be indented or not, depending on
+%D the setting of \type{\parindent}, the first token of a
+%D paragraph and/or user suppressed or forced indentation.
+%D
+%D Because the actual typesetting is based on both explicit
+%D user and implicit system actions, visualization is only
+%D possible for the user supplied \type{\indent},
+%D \type{\noindent}, and \type{\par}. Other
+%D 'clever' tricks will quite certainly lead to more failures
+%D than successes, so we only support these three explicit
+%D primitives and one macro:
+
+\unexpanded\def\showparagraphcue#1#2#3#4#5%
+ {\bgroup
+ \scratchdimen#1\relax
+ \dontinterfere
+ \dontcomplain
+ %boxrulewidth5\testrulewidth
+ #3#4\relax
+ \setbox\scratchbox\normalhbox to \scratchdimen
+ {#2{\ruledhbox to \scratchdimen
+ {\vrule #5 20\testrulewidth \s!width \zeropoint
+ \normalhss}}}%
+ \smashbox\scratchbox
+ \normalpenalty\plustenthousand
+ \box\scratchbox
+ \egroup}
+
+\unexpanded\def\ruledhanging
+ {\ifdim\hangindent>\zeropoint
+ \ifnum\hangafter<\zerocount
+ \normalhbox
+ {%boxrulewidth5\testrulewidth
+ \setbox\scratchbox\ruledhbox to \hangindent
+ {\scratchdimen\strutht
+ \advance\scratchdimen \strutdp
+ \vrule
+ \s!width \zeropoint
+ \s!height \zeropoint
+ \s!depth -\hangafter\scratchdimen}%
+ \normalhskip-\hangindent
+ \smashbox\scratchbox
+ \raise\strutht\box\scratchbox}%
+ \fi
+ \fi}
+
+\unexpanded\def\ruledparagraphcues
+ {\bgroup
+ \dontcomplain
+ \normalhbox to \zeropoint
+ {\ifdim\leftskip>\zeropoint\relax
+ \showparagraphcue\leftskip\llap\relax\relax\!!depth
+ \normalhskip-\leftskip
+ \fi
+ \ruledhanging
+ \normalhskip\hsize
+ \ifdim\rightskip>\zeropoint\relax
+ \normalhskip-\rightskip
+ \showparagraphcue\rightskip\relax\relax\relax\!!depth
+ \fi}%
+ \egroup}
+
+\unexpanded\def\ruledpar
+ {\relax
+ \ifhmode
+ \showparagraphcue{40\testrulewidth}\relax\rightrulefalse\relax\s!height
+ \fi
+ \normalpar}
+
+\unexpanded\def\rulednoindent
+ {\relax
+ \normalnoindent
+ \ruledparagraphcues
+ \showparagraphcue{40\testrulewidth}\llap\leftrulefalse\relax\s!height}
+
+\unexpanded\def\ruledindent
+ {\relax
+ \normalnoindent
+ \ruledparagraphcues
+ \ifdim\parindent>\zeropoint
+ \showparagraphcue\parindent\relax\relax\relax\s!height
+ \else
+ \showparagraphcue{40\testrulewidth}\llap\relax\relax\s!height
+ \fi
+ \normalhskip\parindent}
+
+\unexpanded\def\dontshowimplicits
+ {\let\noindent \normalnoindent
+ \let\indent \normalindent
+ \let\par \normalpar}
+
+\unexpanded\def\showimplicits
+ {\testrulewidth \defaulttestrulewidth
+ \let\noindent \rulednoindent
+ \let\indent \ruledindent
+ \let\par \ruledpar}
+
+%D The next few||line examples show the four cues. Keep in
+%D mind that we only see them when we explicitly open or close
+%D a paragraph.
+%D
+%D \bgroup
+%D \def\voorbeeld#1%
+%D {#1Visualizing some \TeX\ primitives and Plain \TeX\
+%D macros can be very instructive, at least it is to me.
+%D Here we see {\tt\string#1} and {\tt\string\ruledpar} in
+%D action, while {\tt\string\parindent} equals
+%D {\tt\the\parindent}.\ruledpar}
+%D
+%D \showimplicits
+%D
+%D \voorbeeld \indent
+%D \voorbeeld \noindent
+%D
+%D \parindent=60pt
+%D
+%D \voorbeeld \indent
+%D \voorbeeld \noindent
+%D
+%D \startnarrower
+%D \voorbeeld \indent
+%D \voorbeeld \noindent
+%D \stopnarrower
+%D \egroup
+%D
+%D These examples also demonstrate the visualization of
+%D \type {\leftskip} and \type {\rightskip}. The macro
+%D \type {\nofruledbaselines} determines the number of lines
+%D shown.
+
+\newcounter\ruledbaselines
+
+\def\nofruledbaselines{3}
+
+\unexpanded\def\ruledbaseline
+ {\vrule \s!width \zeropoint
+ \bgroup
+ \dontinterfere
+ \doglobal\increment\ruledbaselines
+ \scratchdimen\nofruledbaselines\baselineskip
+ \setbox\scratchbox\normalvbox to 2\scratchdimen
+ {\leaders
+ \normalhbox
+ {\strut
+ \vrule
+ \s!height \testrulewidth
+ \s!depth \testrulewidth
+ \s!width 120\points}
+ \normalvfill}%
+ \smashbox\scratchbox
+ \advance\scratchdimen \strutheightfactor\baselineskip
+ \setbox\scratchbox\normalhbox
+ {\normalhskip -48\points
+ \normalhbox to 24\points
+ {\normalhss
+ {\ttxx\ruledbaselines}%
+ \normalhskip6\points}%
+ \raise\scratchdimen\box\scratchbox}%
+ \smashbox\scratchbox
+ \box\scratchbox
+ \egroup}
+
+\unexpanded\def\showbaselines
+ {\testrulewidth\defaulttestrulewidth
+ \EveryPar{\ruledbaseline}}
+
+%D \macros
+%D {showpagebuilder}
+%D
+%D The next tracing option probaly is only of use to me and a
+%D few \CONTEXT\ hackers.
+
+\unexpanded\def\showpagebuilder
+ {\EveryPar{\doshowpagebuilder}}
+
+\unexpanded\def\doshowpagebuilder
+ {\strut\llap
+ {\startcolor[blue]\vl
+ \high{\infofont v:\the\vsize }\vl
+ \high{\infofont g:\the\pagegoal }\vl
+ \high{\infofont t:\the\pagetotal}\vl
+ \stopcolor}}
+
+%D \macros
+%D {colormarkbox,rastermarkbox}
+%D
+%D This macro is used in the pagebody routine. No other use
+%D is advocated here.
+%D
+%D \starttyping
+%D \colormarkbox0
+%D \stoptyping
+
+\def\colormarkoffset{\cutmarkoffset}
+\def\colormarklength{\cutmarklength}
+
+\def\dodocolorrangeA#1%
+ {\fastcolored[#1]{\hrule\s!width3em\s!height\scratchdimen\s!depth\zeropoint}}
+
+\def\docolorrangeA#1 #2 %
+ {\vbox
+ {\hsize3em % \scratchdimen
+ \ifcase#1\or
+ \dodocolorrangeA{c=#2}\or
+ \dodocolorrangeA{m=#2}\or
+ \dodocolorrangeA{y=#2}\or
+ \dodocolorrangeA{m=#2,y=#2}\or
+ \dodocolorrangeA{c=#2,y=#2}\or
+ \dodocolorrangeA{c=#2,m=#2}\fi
+ \ifdim\scratchdimen>1ex
+ \vskip-\scratchdimen
+ \vbox to \scratchdimen
+ {\vss\hbox to 3em{\hss#2\hss}\vss}%
+ \fi}}
+
+\def\colorrangeA#1%
+ {\vbox
+ {\startcolor[\s!white]%
+ \scratchdimen\dimexpr(-\colormarklength*4+\tractempheight+\tractempdepth)/21\relax
+ \offinterlineskip
+ \docolorrangeA #1 1.00 \docolorrangeA #1 0.95
+ \docolorrangeA #1 0.75
+ \docolorrangeA #1 0.50
+ \docolorrangeA #1 0.25 \docolorrangeA #1 0.05
+ \docolorrangeA #1 0.00
+ \stopcolor}}
+
+\def\docolorrangeB #1 #2 #3 #4 #5 %
+ {\fastcolored
+ [\c!c=#2,\c!m=#3,\c!y=#4,\c!k=#5]
+ {\vrule\s!width\scratchdimen\s!height\colormarklength\s!depth\zeropoint}%
+ \ifdim\scratchdimen>2em
+ \hskip-\scratchdimen
+ \vbox to \colormarklength
+ {\vss\hbox to \scratchdimen{\hss#1\hss}\vss}%
+ \fi}
+
+\def\colorrangeB
+ {\hbox
+ {\startcolor[\s!white]%
+ \scratchdimen\dimexpr(-\colormarklength*\plustwo+\tractempwidth)/11\relax
+ \docolorrangeB .5~C .5 0 0 0
+ \docolorrangeB .5~M 0 .5 0 0
+ \docolorrangeB .5~Y 0 0 .5 0
+ \docolorrangeB .5~K 0 0 0 .5
+ \docolorrangeB C 1 0 0 0
+ \docolorrangeB G 1 0 1 0
+ \docolorrangeB Y 0 0 1 0
+ \docolorrangeB R 0 1 1 0
+ \docolorrangeB M 0 1 0 0
+ \docolorrangeB B 1 1 0 0
+ \docolorrangeB K 0 0 0 1
+ \stopcolor}}
+
+\def\docolorrangeC#1 %
+ {\fastcolored
+ [\c!s=#1]%
+ {\vrule\s!width\scratchdimen\s!height\colormarklength\s!depth\zeropoint}%
+ \ifdim\scratchdimen>2em
+ \hskip-\scratchdimen
+ \vbox to \colormarklength
+ {\vss\hbox to \scratchdimen{\hss#1\hss}\vss}%
+ \fi}
+
+\def\colorrangeC
+ {\hbox
+ {\startcolor[\s!white]%
+ \scratchdimen\dimexpr(-\colormarklength*2+\tractempwidth)/14\relax
+ \docolorrangeC 1 \docolorrangeC .95
+ \docolorrangeC .9 \docolorrangeC .85
+ \docolorrangeC .8 \docolorrangeC .75
+ \docolorrangeC .7
+ \docolorrangeC .6
+ \docolorrangeC .5
+ \docolorrangeC .4
+ \docolorrangeC .3
+ \docolorrangeC .2
+ \docolorrangeC .1
+ \docolorrangeC 0
+ \stopcolor}}
+
+\def\docolormarkbox#1#2%
+ {\tractempheight\ht#2%
+ \tractempdepth \dp#2%
+ \tractempwidth \wd#2%
+ \setbox#2\hbox
+ {\scratchdimen\dimexpr\colormarklength/2\relax
+ \forgetall
+ \ssxx
+ \setbox\scratchbox\vbox
+ {\offinterlineskip
+ \vskip\dimexpr-\colormarkoffset\scratchdimen-2\scratchdimen\relax
+ \ifcase#1\relax
+ \vskip\dimexpr\colormarklength+\scratchdimen+\tractempheight\relax
+ \else
+ \hbox to \tractempwidth{\hss\hbox{\colorrangeB}\hss}%
+ \vskip\colormarkoffset\scratchdimen
+ \vbox to \tractempheight
+ {\vss
+ \hbox to \tractempwidth
+ {\llap{\colorrangeA1\hskip\colormarkoffset\scratchdimen}\hfill
+ \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA4}}%
+ \vss
+ \hbox to \tractempwidth
+ {\llap{\colorrangeA2\hskip\colormarkoffset\scratchdimen}\hfill
+ \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA5}}%
+ \vss
+ \hbox to \tractempwidth
+ {\llap{\colorrangeA3\hskip\colormarkoffset\scratchdimen}\hfill
+ \rlap{\hskip\colormarkoffset\scratchdimen\colorrangeA6}}%
+ \vss}%
+ \fi
+ \vskip\colormarkoffset\scratchdimen
+ \hbox to \tractempwidth
+ {\hss\lower\tractempdepth\hbox{\colorrangeC}\hss}}%
+ \ht\scratchbox\tractempheight
+ \dp\scratchbox\tractempdepth
+ \wd\scratchbox\zeropoint
+ \box\scratchbox
+ \box#2}%
+ \wd#2\tractempwidth
+ \ht#2\tractempheight
+ \dp#2\tractempdepth}
+
+\unexpanded\def\colormarkbox {\docolormarkbox\plusone } % #1
+\unexpanded\def\rastermarkbox{\docolormarkbox\zerocount} % #1
+
+%D \macros
+%D {showwhatsits, dontshowwhatsits}
+%D
+%D \TEX\ has three so called whatsits: \type {\mark}, \type
+%D {\write} and \type {\special}. The first one keeps track of
+%D the current state at page boundaries, the last two are used
+%D to communicate to the outside world. Due to fact that
+%D especially \type {\write} is often used in conjunction with
+%D \type {\edef}, we can only savely support that one in \ETEX.
+%D
+%D \bgroup \showwhatsits \setupcolors[state=start]
+%D
+%D Whatsits show up \color[blue]{in color} and are
+%D characterized bij their first character.\footnote [some note]
+%D {So we may encounter \type {w}, \type {m} and \type{s}.}
+%D They are \writestatus{dummy}{demo}\color[yellow]{stacked}.
+%D
+%D \egroup
+
+\newif\ifimmediatewrite
+
+\let\supernormalmark \normalmark % mark may already been superseded
+\let\supernormalmarks \normalmarks % mark may already been superseded
+
+\unexpanded\def\showwhatsits
+ {\protected\def\normalmark {\visualwhatsit100+m\supernormalmark }%
+ \protected\def\normalmarks{\visualwhatsit100+m\supernormalmarks}%
+ \protected\def\special {\visualwhatsit0100s\normalspecial }%
+ \protected\def\write {\visualwhatsit001-w\normalwrite }%
+ \let\immediate\immediatewhatsit
+ \appendtoks\dontshowwhatsits\to\everystoptext}
+
+\unexpanded\def\immediatewhatsit
+ {\bgroup\futurelet\next\doimmediatewhatsit}
+
+\unexpanded\def\doimmediatewhatsit
+ {\ifx\next\write
+ \egroup\immediatewritetrue
+ \else
+ \egroup\expandafter\normalimmediate
+ \fi}
+
+\unexpanded\def\dontshowwhatsits
+ {\let\immediate \normalimmediate
+ \let\normalmark\supernormalmark
+ \let\special \normalspecial
+ \let\write \normalwrite}
+
+\unexpanded\def\visualwhatsit#1#2#3#4#5%
+ {\bgroup
+ \pushwhatsit
+ \dontinterfere
+ \dontcomplain
+ \dontshowcomposition
+ \dontshowwhatsits
+ \ttx
+ \ifvmode\donetrue\else\donefalse\fi
+ \setbox\scratchbox\hbox
+ {\ifdone
+ \colored[r=#1,g=#2,b=#3]{#5}% temp hack
+ \else
+ \colored[s=0]{#5}% temp hack
+ \fi}%
+ \setbox\scratchbox\hbox
+ {\ifdone
+ \colored[r=#1,g=#2,b=#3]{\vrule\s!width\wd\scratchbox}% temp hack
+ \else
+ \colored[s=0]{\vrule\s!width\wd\scratchbox}% temp hack
+ \fi
+ \hskip-\wd\scratchbox\box\scratchbox}%
+ \scratchdimen1ex
+ \setbox\scratchbox\hbox
+ {\ifdone\hskip\else\raise#4\fi\scratchdimen\box\scratchbox}%
+ \smashbox\scratchbox
+ \ifdone\nointerlineskip\fi
+ \box\scratchbox
+ \ifvmode\nointerlineskip\fi
+ \popwhatsit
+ \egroup
+ \ifimmediatewrite
+ \immediatewritefalse
+ \expandafter\normalimmediate
+ \fi}
+
+\unexpanded\def\pushwhatsit
+ {\ifzeropt\lastskip
+ \ifcase\lastpenalty
+ \ifzeropt\lastkern
+ \ifhmode
+ \let\popwhatsit\relax
+ \else
+ \edef\popwhatsit{\prevdepth\the\prevdepth}%
+ \fi
+ \else
+ \ifhmode
+ \edef\popwhatsit{\kern\the\lastkern}\unkern
+ \else
+ \edef\popwhatsit{\kern\the\lastkern\prevdepth\the\prevdepth}%
+ \kern-\lastkern
+ \fi
+ \fi
+ \else
+ \ifhmode
+ \edef\popwhatsit{\the\lastpenalty}%
+ \unpenalty
+ \else
+ \edef\popwhatsit{\penalty\the\lastpenalty\prevdepth\the\prevdepth}%
+ %\nobreak
+ \fi
+ \fi
+ \else
+ \ifhmode
+ \edef\popwhatsit{\hskip\the\lastskip}\unskip
+ \else
+ \edef\popwhatsit{\vskip\the\lastskip\prevdepth\the\prevdepth}%
+ \vskip-\lastskip
+ \fi
+ \fi}
+
+%D The next macro can be used to keep track of classes of
+%D boxes (handy for development cq.\ tracing).
+
+\def\dodotagbox#1#2#3% can be reimplemented
+ {\def\next##1##2##3##4%
+ {\vbox to \ht#2{##3\hbox to \wd#2{##1#3##2}##4}}%
+ \processaction
+ [#1]
+ [ l=>\next\relax\hfill\vfill\vfill,
+ r=>\next\hfill\relax\vfill\vfill,
+ t=>\next\hfill\hfill\relax\vfill,
+ b=>\next\hfill\hfill\vfill\relax,
+ lt=>\next\relax\hfill\relax\vfill,
+ lb=>\next\relax\hfill\vfill\relax,
+ rt=>\next\hfill\relax\relax\vfill,
+ rb=>\next\hfill\relax\vfill\relax,
+ tl=>\next\relax\hfill\relax\vfill,
+ bl=>\next\relax\hfill\vfill\relax,
+ tr=>\next\hfill\relax\relax\vfill,
+ br=>\next\hfill\relax\vfill\relax,
+ \s!default=>\next\hfill\hfill\vfill\vfill,
+ \s!unknown=>\next\hfill\hfill\vfill\vfill]}
+
+\def\dotagbox[#1]#2%
+ {\bgroup
+ \dowithnextbox
+ {\setbox\scratchbox\flushnextbox
+ \setbox\nextbox\ifhbox\nextbox\hbox\else\vbox\fi
+ \bgroup
+ \startoverlay
+ {\copy\scratchbox}
+ {\dodotagbox{#1}\scratchbox{\framed
+ [\c!background=\v!color,\c!backgroundcolor=\v!gray]{#2}}}
+ \stopoverlay
+ \egroup
+ \nextboxwd\the\wd\scratchbox
+ \nextboxht\the\ht\scratchbox
+ \nextboxdp\the\dp\scratchbox
+ \flushnextbox
+ \egroup}}
+
+\unexpanded\def\tagbox
+ {\dosingleempty\dotagbox}
+
+%D \macros
+%D {coloredhbox,coloredvbox,coloredvtop,
+%D coloredstrut}
+%D
+%D The following visualizations are used in some of the manuals:
+
+\definecolor[boxcolor:ht][r=.5,g=.75,b=.5]
+\definecolor[boxcolor:dp][r=.5,g=.5,b=.75]
+\definecolor[boxcolor:wd][r=.75,g=.5,b=.5]
+\definecolor[strutcolor] [r=.5,g=.25,b=.25]
+
+\unexpanded\def\coloredbox#1%
+ {\dowithnextbox{#1{\hbox
+ {\blackrule[\c!width=\nextboxwd,\c!height=\nextboxht,\c!depth=\zeropoint,\c!color=boxcolor:ht]%
+ \hskip-\nextboxwd
+ \blackrule[\c!width=\nextboxwd,\c!height=\zeropoint,\c!depth=\nextboxdp,\c!color=boxcolor:dp]%
+ \hskip-\nextboxwd
+ \box\nextbox}}}#1}
+
+\unexpanded\def\coloredhbox{\coloredbox\hbox}
+\unexpanded\def\coloredvbox{\coloredbox\vbox}
+\unexpanded\def\coloredvtop{\coloredbox\vtop}
+
+\unexpanded\def\coloredstrut
+ {\color[strutcolor]{\def\strutwidth{2\points}\setstrut\strut}}
+
+\protect
+
+\continueifinputfile{m-visual.mkiv}
+
+\starttext
+ \simplethesis
+\stoptext
diff --git a/tex/context/modules/mkiv/m-zint.mkiv b/tex/context/modules/mkiv/m-zint.mkiv
new file mode 100644
index 000000000..4957c8461
--- /dev/null
+++ b/tex/context/modules/mkiv/m-zint.mkiv
@@ -0,0 +1,112 @@
+%D \module
+%D [ file=m-zint,
+%D version=2010.12.07,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Zint Barcode Generator,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Using \type {zint} seems to be the easiest way to generate
+%D (PDF417) barcodes so therefore we now have this module. There
+%D are proper (also windows) binaries at:
+%D
+%D \starttyping
+%D http://www.zint.org.uk
+%D \stoptyping
+%D
+%D There is a bit more code than needed as we want to be able to
+%D feed names.
+
+\startluacode
+
+moduledata.zint = { }
+
+local format, lower, gsub = string.format, string.lower, string.gsub
+local patterns = lpeg.patterns
+
+local zint = "zint" -- '"c:/program files/zint/zint.exe"'
+local defaultcode = "PDF417"
+
+local whitespace = patterns.whitespace
+local spaces = whitespace^0
+local key = (spaces / "") * patterns.digit^0 * (patterns.colon * spaces / "")
+local value = (whitespace / "" + (1 - key))^1
+local pattern = lpeg.Cf(lpeg.Ct("") * (lpeg.Cg((lpeg.Cs(key) / tonumber) * (lpeg.Cs(value) / lower)) + patterns.anything)^0,rawset)
+
+local reverse
+
+local function cleancode(code)
+ if not code or code == "" then
+ code = defaultcode
+ end
+ return lower(gsub(code," ",""))
+end
+
+local function numberofcode(code)
+ if not reverse then
+ local types = os.resultof(format("%s --types",zint)) or ""
+ local formats = lpeg.match(pattern,types)
+ if not formats or not next(formats) then
+ return code
+ end
+ reverse = table.swapped(formats) or { }
+ end
+ code = cleancode(code)
+ return reverse[code] or code
+end
+
+function moduledata.zint.generate(code,data,suffix,options)
+ if not data or data == "" then
+ data = "unset"
+ end
+ local code = cleancode(code)
+ local base = format("zint-%s-%s",code,md5.hex(data))
+ local name = file.addsuffix(base,suffix or "eps")
+ if not lfs.isfile(name) then
+ local temp = file.addsuffix(base,"tmp")
+ local code = numberofcode(code)
+ logs.simple("using 'zint' to generate '%s'",base)
+ io.savedata(temp,data)
+ os.execute(format('%s --barcode=%s --output="%s" --input="%s" %s',zint,code,name,temp,options or ""))
+ os.remove(temp)
+ end
+ return name
+end
+
+\stopluacode
+
+\unprotect
+
+\unexpanded\def\barcode[#1]% [alternative=,text=]
+ {\bgroup
+ \getdummyparameters
+ [\c!alternative=,\c!text=,#1]%
+ \externalfigure
+ [\cldcontext{moduledata.zint.generate("\dummyparameter\c!alternative",\!!bs\dummyparameter\c!text\!!es)}]%
+ [#1,\c!alternative=,\c!text=]%
+ \egroup}
+
+\protect
+
+\continueifinputfile{m-zint.mkiv}
+
+\starttext
+
+ \externalfigure[\cldcontext{moduledata.zint.generate("PDF417",[[Hans Hagen]])}]
+ \blank
+ \externalfigure[\cldcontext{moduledata.zint.generate("PDF417","Ton Otten")}]
+ \blank
+ \externalfigure[\cldcontext{moduledata.zint.generate("ISBN","9789490688011")}]
+ \blank
+ \barcode[text=Does It Work?,width=\textwidth]
+ \blank
+ \barcode[alternative=isbn,text=9789490688011,width=3cm]
+
+\stoptext
+
+
diff --git a/tex/context/modules/mkiv/ppchtex.mkiv b/tex/context/modules/mkiv/ppchtex.mkiv
new file mode 100644
index 000000000..d1167d414
--- /dev/null
+++ b/tex/context/modules/mkiv/ppchtex.mkiv
@@ -0,0 +1,3445 @@
+%D \module
+%D [ file=ppchtex,
+%D version=1997.03.19,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=\PPCHTEX\ (Plain Pictex Context cHemie \TEX),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D suggestions={Tobias Burnus, Dirk Kuypers \& Ton Otten},
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\endinput
+
+% option=test => boxes
+% dummy => file
+% final => file / local run
+%
+% constante van phantom in definitie ONE: \setchemicaltextwidth 300
+%
+% it would be interesting to rewrite this module with todays
+% experiences and new context functionality, maybe ...
+
+% Deze module ondersteunt het zetten van chemische
+% (structuur)formules. Hoewel de macro' zijn afgestemd op
+% CONTEXT, zijn ze ook buiten deze zetomgeving te gebruiken.
+%
+% Dit is, afgezien van updates, de definitieve versie van
+% PPCHTEX. Gebruikersgemak, eenvoud, flexibiliteit, en
+% snelheid zijn inmiddels redelijk geoptimaliseerd. Dit neemt
+% niet weg dat hier en daar nog verbetering mogelijk is. Dit
+% zal dan ook nog gebeuren.
+%
+% Volgende versies zullen tenminste dezelfde functionaliteit
+% hebben. We houden ons natuurlijk het recht voor de kwaliteit
+% van de output te verbeteren. Daarnaast staan nog op het
+% wensenlijstje:
+%
+% - optimaliseren in termen van proces-tijd
+% - aanpassen naamgeving van interne macro's
+% - toevoegen van functionaliteit
+% - in \x!-vorm omzetten van GIVES, TB enz.
+%
+% De mix tussen engels en nederlands lijkt soms verwarrend.
+% Meestal zijn verborgen macro's engels en zichtbare macro's
+% nederlands. Het gebruik van [ ] en { } sluit aan op andere
+% Context-macro's. Hetzelfde geldt voor instellingen en
+% \start-\stop-constructies.
+%
+% De schijnbaar overbodige \bgroup-\egroup constructie
+% garandeert aansluiting bij de Context-macro's voor het
+% plaatsen van figuren, tabellen en andere floats.
+%
+% Binnen Context worden de macro's geladen met
+% \gebruikextras[chemie]. Daarbij wordt een passende melding
+% getoont. Buiten Context genereren we een melding:
+
+\doifundefined{usemodule}
+ {\writestatus{loading}{ConTeXt Chemical Macro's / 1996.3.1}}
+
+% Er kan gebruik worden gemaakt van PiCTeX of PStricks. Een
+% van deze pakketten moet van te voren zijn geladen.
+%
+% \input prepictex.tex (i.g.v. LaTeX)
+% \input pictex.tex
+% \input postpictex.tex (i.g.v. LaTeX)
+%
+% of:
+%
+% \input multido.tex
+% \input pstricks.tex
+% \input pst-plot.tex
+%
+% In \CONTEXT\ kan men de modules m-pictex en m-pstricks
+% gebruiken. De eerste module laad of efficiente wijze PiCTeX
+% en de tweede module koppelt het PSTRICKS kleurmechanisme
+% aan dat van \CONTEXT.
+
+% PSTricks: {-\chemicalangle} instead of {*0}, which produces
+% faulty ps code when \chemicalangle=0
+
+\startcommands dutch english german
+
+ gotochemical: naarchemie gotochemical zurchemie
+ setupchemical: stelchemiein setupchemical stellechemieein
+ startchemical: startchemie startchemical startchemie
+ stopchemical: stopchemie stopchemical stopchemie
+ definechemical: definieerchemie definechemical definierechemie
+ chemical: chemie chemical chemie
+ toptext: boventekst toptext textueber
+ bottext: ondertekst bottext textunter
+ midtext: middentekst midtext textmitte
+
+\stopcommands
+
+\doifundefined{fiverm} % In the more recent LaTeX versions
+ {\font\fiverm=cmr5 } % \fiverm is no longer (pre)defined.
+
+\newconstant\chemicaldrawingmode
+
+\doifelsedefined{beginpicture} % PiCTeX
+ {\doifelsedefined{startMPdrawing}
+ {\chemicaldrawingmode\plustwo } % MetaPost
+ {\chemicaldrawingmode\zerocount}} % raw
+ {\doifelsedefined{psaxes}
+ {\chemicaldrawingmode\plusone } % PSTricks
+ {\chemicaldrawingmode\plusthree}} % unknown
+
+\ifcase\chemicaldrawingmode
+ \writestatus{ppchtex}{using PiCTeX}
+\or
+ \writestatus{ppchtex}{using PSTricks (still experimental)}
+ \writestatus{ppchtex}{automatic sizing not (yet) supported}
+\or
+ \writestatus{ppchtex}{using PiCTeX and MetaPost}
+\else
+ \writestatus{ppchtex}{load PiCTeX (+pre/post) or PSTricks (+pst_plot) first}
+ \bgroup
+ \read16 to \exit
+ \egroup
+ \expandafter\endinput
+\fi
+
+%I n=Chemie
+%I c=\stelchemiein,\chemie
+%I
+%I Chemische formules kunnen worden gezet met behulp van de
+%I onderstaande commando's:
+%I
+%I buiten $ en $$ :
+%I
+%I \chemie[segmenten][symbolen]
+%I
+%I \startchemie[instellingen]
+%I \chemie...
+%I \chemie...
+%I \stopchemie
+%I
+%I en binnen $ en $$:
+%I
+%I \chemie{}{}
+%I
+%I Voor tekst, uitleg en voorbeelde verwijzen we vooralsnog
+%I naar de handleiding.
+%P
+%I Het gedrag van de macro's kan worden ingesteld met:
+%I
+%I \stelchemiein[breedte=,hoogte=,links=,rechts=,boven=,
+%I onder=,korps=,schaal=,status=,assenstelsel=,kader=,
+%I variant=,optie=,formaat=,tekstformaat=,resolutie=,
+%I offset=,letter=]
+%I
+%I Structuren kunnen worden voorgedefinieerd met het commando
+%I
+%I \definieerchemie[naam]{\chemie...}
+
+%S \startsetup
+%S \command
+%S [\!stelchemiein]
+%S \type
+%S [\c!vars!]
+%S \variable
+%S [\c!breedte]
+%S [\c!number!,\v!passend]
+%S [0]
+%S \variable
+%S [\c!hoogte]
+%S [\c!number!,\v!passend]
+%S [0]
+%S \variable
+%S [\c!links]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!rechts]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!boven]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!onder]
+%S [\c!number!]
+%S [0]
+%S \variable
+%S [\c!resolutie]
+%S [\c!number!]
+%S [\outputresolution]
+%S \variable
+%S [\c!korps]
+%S [10pt,11pt,12pt]
+%S [\bodyfontsize]
+%S \variable
+%S [\c!schaal]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!middel]
+%S \variable
+%S [\c!formaat]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!groot]
+%S \variable
+%S [\c!tekstformaat]
+%S [\v!klein,\v!middel,\v!groot]
+%S [\v!groot]
+%S \variable
+%S [\c!status]
+%S [\v!start,\v!stop]
+%S [\v!start]
+%S \variable
+%S [\c!kader]
+%S [\v!aan,\v!uit]
+%S [\v!uit]
+%S \variable
+%S [\c!assenstelsel]
+%S [\v!aan,\v!uit]
+%S [\v!uit]
+%S \variable
+%S [\c!optie]
+%S [\v!test]
+%S []
+%S \variable
+%S [\c!variant]
+%S [1,2]
+%S [1]
+%S \variable
+%S [\c!offset]
+%S [HIGH,LOW]
+%S [LOW]
+%S \variable
+%S [\c!letter]
+%S [\c!command!]
+%S [\rm]
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [\v!startchemie]
+%S \type
+%S [\c!vars!\c!stp!]
+%S \inheritvariable
+%S [\v!stelchemiein]
+%S []
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [\v!chemie]
+%S \type
+%S [\c!vals!\c!vals!]
+%S \value
+%S [\c!list!]
+%S []
+%S \value
+%S [\c!list!]
+%S []
+%S \stopsetup
+
+%S \startsetup
+%S \command
+%S [definieerchemie]
+%S \type
+%S [\c!val!\c!arg!]
+%S \value
+%S [\c!text!]
+%S []
+%S \stopsetup
+
+\unprotect
+
+% Om te voorkomen dat sub- en superscripts botsen passen we
+% wat fontdimen's aan (Knuth, The TeXBook, p179). Helaas
+% kunnen deze instellingen niet lokaal worden gehouden door
+% groeperen, vandaar dat een en ander moet worden geset n
+% gereset.
+%
+% Er dient een relatie te worden gelegd met de afmetingen
+% van de letters. In een eerdere versie werden daartoe de
+% \fontdimen's opgehoogd. Omdat dit problemen gaf bij
+% scaled fonts, is bij nader inzien gekozen voor de
+% onderstaande oplossing, waarbij de nieuwe waarden worden
+% afgeleid van de x-height (\fontexheight). De factor 0.70
+% is min of meer experimenteel vastgesteld. Soms worden de
+% regels iets verder uit elkaar gezet. Jammer. Italic fonts
+% hebben grotere cijfers en vallen min of meer uit de boot.
+
+\newif\ifloweredsubscripts % this will be redone in the mkiv ways
+
+\def\setsubscripts
+ {\def\dosetsubscript##1##2##3%
+ {\dimen0=##3\fontexheight##2%
+ \setxvalue{@@\string##1\string##2}{\the##1##2\relax}%
+ ##1##2=\dimen0\relax}%
+ \def\dodosetsubscript##1##2%
+ {\dosetsubscript{##1}{\textfont 2}{##2}%
+ \dosetsubscript{##1}{\scriptfont 2}{##2}%
+ \dosetsubscript{##1}{\scriptscriptfont2}{##2}}%
+ %dodosetsubscript\mathsupnormal {?}%
+ \dodosetsubscript\mathsubnormal {.7}%
+ \dodosetsubscript\mathsubcombined{.7}%
+ \global\loweredsubscriptstrue}
+
+\def\resetsubscripts
+ {\ifloweredsubscripts
+ \def\doresetsubscript##1##2%
+ {\dimen0=\getvalue{@@\string##1\string##2}\relax
+ ##1##2=\dimen0}%
+ \def\dodoresetsubscript##1%
+ {\doresetsubscript{##1}{\textfont2}%
+ \doresetsubscript{##1}{\scriptfont2}%
+ \doresetsubscript{##1}{\scriptscriptfont2}}%
+ %dodoresetsubscript\mathsupnormal
+ \dodoresetsubscript\mathsubnormal
+ \dodoresetsubscript\mathsubcombined
+ \global\loweredsubscriptsfalse
+ \fi}
+
+\ifx\Umathchar\undefined \else
+ % for the moment we nil them, soon we will have a proper
+ % way to deal with this
+ \let\setsubscripts \relax
+ \let\resetsubscripts\relax
+\fi
+
+\def\doresetsubscripts
+ {\resetsubscripts}
+
+\def\sethighsubscripts
+ {\resetsubscripts
+ \let\dosetsubscripts=\relax}
+
+\def\setlowsubscripts
+ {\def\dosetsubscripts{\setsubscripts}}
+
+\setlowsubscripts
+
+\newcount\horchemical % t.z.t. \newcounter
+\newcount\verchemical % t.z.t. \newcounter
+\newcount\txtchemical % t.z.t. \newcounter
+\newcount\levchemical % t.z.t. \newcounter
+
+\newif\ifinchemical \inchemicalfalse
+\newif\iffixedchemical \fixedchemicalfalse
+
+\newbox\chemicalsymbols
+
+% Eigenlijk moeten de constanten en variabelen in cont-nl.tex
+% staan. Dit pakket is echter relatief onafhankelijk van CONTEXT.
+
+\definesystemvariable {chemical}
+
+\definesystemconstant {chemical}
+
+\definesystemconstant {translate}
+\definesystemconstant {distance}
+\definesystemconstant {mirror}
+\definesystemconstant {rotate}
+\definesystemconstant {substitute}
+\definesystemconstant {angle}
+
+\definesystemconstant {executechemical}
+\definesystemconstant {chemicaltextelement}
+\definesystemconstant {chemicallinesegment}
+\definesystemconstant {chemicalcircsegment}
+
+\def\chemicalspace {\quad}
+
+% begin van experiment:
+%
+% De onderstaande twee macro's kunnen worden gebruikt voor
+% bijvoorbeeld een interactiemechanisme.
+%
+% \localgotochemical {verwijzing} {tekst}
+% \localthisischemical {verwijzing}
+
+\def\dowithchemical%
+ {}
+
+\def\localgotochemical#1#2{\gotobox{#2}[#1]}
+\def\localthisischemical#1{\pagereference[#1]}
+
+% eind van experiment
+
+\def\setchemicalmaximum #1
+ {\def\maxchemical{#1}}
+
+\def\doifchemicalnumber#1#2#3%
+ {\doifelsenumber{#1}
+ {\ifnum#1>\maxchemical\relax
+ \writestatus{ppchtex}{number #1 is skipped}%
+ \else
+ #3%
+ \fi}
+ {\unknownchemical{#2}}}%
+
+\newif\ifsmallchemicaltext
+
+\let\@@localchemicalstyle\empty
+
+\unexpanded\def\setupchemicalformat[#1]%
+ {\processaction
+ [\getvalue{#1\c!size}]
+ [ \v!small=>\def\@@localchemicalformat{\scriptscriptstyle},
+ \v!medium=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi},
+ \v!big=>\def\@@localchemicalformat{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi},
+ \s!unknown=>\def\@@localchemicalformat{\getvalue{#1\c!size}}]%
+ \processaction
+ [\getvalue{#1\c!textsize}]
+ [ \v!small=>\def\@@localchemicalstyle{\scriptscriptstyle},
+ \v!medium=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptscriptstyle\else\scriptstyle\fi},
+ \v!big=>\def\@@localchemicalstyle{\ifsmallchemicaltext\scriptstyle\else\textstyle\fi},
+ \s!unknown=>\def\@@localchemicalstyle{\getvalue{#1\c!textsize}}]%
+ \processaction
+ [\getvalue{#1\c!scale}]
+ [ \v!small=>\def\@@localchemicalscale{500},
+ \v!medium=>\def\@@localchemicalscale{625},
+ \v!big=>\def\@@localchemicalscale{750},
+ \s!unknown=>\def\@@localchemicalscale{\getvalue{#1\c!scale}}]}
+
+\def\@@currentchemicalformat
+ {\ifinchemical
+ \@@localchemicalformat
+ \else
+ \@@localchemicalstyle
+ \fi}
+
+\def\dosetupchemical[#1]%
+ {\getparameters[\??chemical\s!chemical][#1]%
+ \doifelse{\@@chemicalchemicaloffset}{LOW}
+ {\setlowsubscripts}
+ {\sethighsubscripts}%
+ \setupchemicalformat[\??chemical\s!chemical]%
+ \ignorespaces}
+
+\unexpanded\def\setupchemical
+ {\dosingleargument\dosetupchemical}
+
+\def\@@dochemicalstyle% % default mapping
+ {\@@chemicalstyle}
+
+\def\@@dochemicalcolor% % no mapping yet
+ {}
+
+\def\@@chemicalstyle % $inner-style$ % (overloaded)
+ {\@@chemicalchemicalstyle} % $$outer-style$$
+
+\def\@@writechemicalstate#1#2%
+ {}
+
+\def\@@beginchemicallocalpicture
+ {\ifcase\chemicaldrawingmode
+ \beginpicture
+ \or
+ \pspicture(0,0)(0,0) % is this permitted ?
+ \or
+ \pushMPdrawing
+ \startMPdrawing
+ %prologues := 1 ;
+ %input mp-tool ;
+ u := 10*\@@chemicalunit;
+ bboxmargin := 0pt ;
+ pickup pencircle scaled 2u ; % ???
+ \stopMPdrawing
+ \beginpicture
+ \fi}
+
+\def\@@endchemicallocalpicture#1#2%
+ {\ifcase\chemicaldrawingmode
+ \endpicture
+ \or
+ \endpspicture
+ \or
+ \resetchemicalcoordinates
+ \setbox2\hbox{\ignoreMPboxdepth\getMPdrawing}%
+ \wd2\zeropoint
+ \ht2\zeropoint
+ \dp2\zeropoint
+ \put {\box2} at 0 0
+ \endpicture
+ \popMPdrawing
+ \fi}
+
+\def\@@beginchemicalpicture#1#2#3#4%
+ {\ifnum\chemicaldrawingmode=1
+ \pspicture(#1,#3)(#2,#4)%
+ \def\account##1##2{}%
+ \psaxes[axesstyle=none,labels=none,ticks=none](#1,#3)(#2,#4)%
+ \else
+ \beginpicture
+ \setplotarea
+ x from {#1} to {#2},
+ y from {#3} to {#4}
+ \iffixedchemical
+ \accountingon
+ \def\account##1##2%
+ {\put {} at {##1} {##2} }%
+ \else
+ \accountingoff
+ \def\account##1##2{}%
+ \fi
+ \fi
+ \ignorespaces}
+
+\def\@@endchemicalpicture%
+ {\ifcase\chemicaldrawingmode
+ \put {\box\chemicalsymbols} at 0 0 % elders
+ \endpicture
+ \or
+ \rput(0,0){\box\chemicalsymbols}%
+ \endpspicture
+ \or
+ \put {\box\chemicalsymbols} at 0 0 % elders
+ \ifMPdrawingdone
+ \resetchemicalcoordinates
+ \setbox2\hbox{\ignoreMPboxdepth\getMPdrawing}%
+ \wd2\zeropoint
+ \ht2\zeropoint
+ \dp2\zeropoint
+ \put {\box2} at 0 0 %
+ \fi
+ \endpicture
+ \fi}
+
+\def\@@setchemicalcoordinatesystem#1%
+ {\edef\@@chemicalunit{#1}%
+ \ifcase\chemicaldrawingmode
+ \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> %
+ \or
+ \psset{unit=\@@chemicalunit}%
+ \or
+ \setcoordinatesystem units <\@@chemicalunit,\@@chemicalunit> %
+ \startMPdrawing
+ %input mp-tool ;
+ %prologues := 1 ;
+ u := 10*#1;
+ bboxmargin := 0pt ;
+ pickup pencircle scaled 2u ; % ???
+ \stopMPdrawing
+ \fi}
+
+\ifx\MPdivten\undefined % hack to prevent overflows in mp
+ \def\MPdivten[#1]{\withoutpt\the\dimexpr#1pt/10\relax}
+\fi
+
+\def\@@setchemicalaxis#1#2#3#4%
+ {\ifcase\chemicaldrawingmode
+ \axis
+ bottom shiftedto y=0
+ ticks from {#1} to {#2} by 500 /
+ \axis
+ left shiftedto x=0
+ ticks from {#3} to {#4} by 500 / %
+ \or
+ \psaxes[labels=none,Dx=500,Dy=500](0,0)(#1,#3)(#2,#4)%
+ \or
+ \global\MPdrawingdonetrue
+ % we need to div beforehand because of mp limitations
+ \startMPdrawing
+ x1 := \MPdivten[#1]u ; x2 := \MPdivten[#2]u;
+ y1 := \MPdivten[#3]u ; y2 := \MPdivten[#4]u;
+ draw z1--(x2,y1)--z2--(x1,y2)--cycle ;
+ d := 50u ; dd := 10u ;
+ draw (x1,0)--(x2,0) ;
+ draw (0,y1)--(0,y2) ;
+ for i=d step -d until x1: draw (i,dd)--(i,-dd) ; endfor ;
+ for i=d step d until x2: draw (i,dd)--(i,-dd) ; endfor ;
+ for i=d step -d until y1: draw (-dd,i)--(dd,i) ; endfor ;
+ for i=d step d until y2: draw (-dd,i)--(dd,i) ; endfor ;
+ \stopMPdrawing
+ \fi}
+
+\def\@@setsecondchemicalplotsymbol%
+ {\ifcase\chemicaldrawingmode
+ \!!widtha=50.8mm
+ \divide\!!widtha by \@@chemicalresolution\relax
+ \plotsymbolspacing=\!!widtha
+ \setplotsymbol({\vrule\s!height\!!widtha\s!width\!!widtha})%
+ \fi}
+
+% Something for Dirk:
+
+\newcount \currentchemical
+
+%\newif \ifskipchemical
+
+\def\setchemicaldimensions#1#2#3%
+ {\bgroup
+ \global\advance\currentchemical by 1
+ \dimen0=#1\relax
+ \dimen2=#2\relax
+ \dimen4=#3\relax
+ \setxvalue{chemical::\the\currentchemical}%
+ {\noexpand\docommand{\the\dimen0}{\the\dimen2}{\the\dimen4}}%
+ \egroup}
+
+\ifx\normalchemicalframe\undefined
+ \let\normalchemicalframe\hbox % hook for educational purposes
+\fi
+
+\unexpanded\def\complexstartchemical[#1]%
+ {\copyparameters
+ [\??chemical][\??chemical\s!chemical]
+ [\c!width,\c!height,\c!left,\c!right,\c!top,\c!bottom,
+ \c!bodyfont,\c!size,\c!scale,\c!state,\c!frame,\c!axis,\c!factor,
+ \c!location,\c!option,\c!alternative,\c!resolution,\c!offset,\c!style,
+ \c!color,\c!rulecolor,\c!rulethickness]%
+ \getparameters
+ [\??chemical]
+ [#1]%
+ %
+ \setupchemicalformat[\??chemical]%
+ %
+ \ifnum\chemicaldrawingmode=2
+ \resetMPdrawing
+ \fi
+ %
+ \doif{\@@chemicalalternative}{2}
+ {\@@setsecondchemicalplotsymbol}%
+ %
+ \doif{\@@chemicalaxis}\v!on
+ {\let\chemicalframe\hbox}%
+ %
+ \!!counta=250000
+ \divide\!!counta by \@@localchemicalscale
+ \!!widtha=\@@chemicalbodyfont
+ \divide\!!widtha by \!!counta
+ \@@setchemicalcoordinatesystem{\the\!!widtha}%
+ %
+ % \!!counta = -x \!!countc = -y
+ % \!!countb = +x \!!countd = +y
+ %
+ \def\calculateaxis##1##2##3##4##5%
+ {##1=##3\relax
+ ##2=##4\relax
+ \ifnum##5=0
+ \ifnum##3=0
+ \ifnum##4=0
+ ##1=2000
+ ##2=2000
+ \fi
+ \fi
+ \else
+ \ifnum##3=0
+ \ifnum##4=0
+ ##1=##5\relax
+ \divide##1 by 2
+ ##2=##1\relax
+ \else
+ ##1=##5\relax
+ \advance##1 by -##2\relax
+ \fi
+ \else
+ \ifnum##4=0
+ ##2=##5\relax
+ \advance##2 by -##1\relax
+ \fi
+ \fi
+ \fi}%
+ \fixedchemicalfalse
+ \doif\@@chemicalwidth\v!fit
+ {\edef\@@chemicalwidth
+ {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}%
+ \fixedchemicaltrue}%
+ \doif\@@chemicalheight\v!fit
+ {\edef\@@chemicalheight
+ {\ifnum\chemicaldrawingmode=1 2000 \else 1 \fi}%
+ \fixedchemicaltrue}%
+ \doifelse\@@chemicallocation\v!intext
+ {\!!counta=0 \!!countb=0
+ \!!counta=0 \!!countd=0 }
+ {\calculateaxis
+ \!!counta\!!countb
+ \@@chemicalleft\@@chemicalright\@@chemicalwidth
+ \calculateaxis
+ \!!countc\!!countd
+ \@@chemicalbottom\@@chemicaltop\@@chemicalheight}%
+ %
+ \edef\@@chemheight {\the\!!countc}%
+ \edef\@@chemdepth {\the\!!countd}%
+ \edef\@@chemicaltop {\the\!!countc}%
+ \edef\@@chemicalbottom{\the\!!countd}%
+ %
+ \doifelseinset\v!on{\@@chemicalframe,\@@chemicalaxis}
+ {\def\@@chemicalborder{\chemicalframe}}
+ {\def\@@chemicalborder{\normalchemicalframe}}%
+ %
+ \setbox0=\hbox\bgroup % this was a \vbox which took \hsize
+ %
+ \@@beginchemicalpicture
+ {-\the\!!counta}{\the\!!countb}
+ {-\the\!!countc}{\the\!!countd}%
+ \doif{\@@chemicalstate}\v!start
+ {\doif\@@chemicalaxis\v!on
+ {\@@setchemicalaxis
+ {-\the\!!counta}{\the\!!countb}
+ {-\the\!!countc}{\the\!!countd}}}%
+ \doifelse\@@chemicaloption\v!test
+ {\def\@@writechemicalstate##1##2%
+ {\convertargument##2\to\ascii
+ \writestatus{##1}{\ascii}}}
+ {\def\@@writechemicalstate##1##2{}}%
+ \ignorespaces}
+
+\def\dostartchemical%
+ {\catcode`\^=\superscriptcatcode% t.b.v. \enableduplication
+ \catcode`\_=\subscriptcatcode % t.b.v. de zekerheid
+ \begingroup
+ \inchemicaltrue
+ \def\toptext##1{\gdef\thetoptext{##1}\ignorespaces}\toptext{}%
+ \def\bottext##1{\gdef\thebottext{##1}\ignorespaces}\bottext{}%
+ \def\midtext##1{\gdef\themidtext{##1}\ignorespaces}\midtext{}%
+ \def\@@chemicalpostponed{}%
+ \complexorsimpleempty\startchemical}
+
+\unexpanded\def\startchemical
+ {\bgroup % t.b.v. ungrouped floats
+ \dostartchemical}
+
+\unexpanded\def\stopchemical
+ {\checkchemicalpicture
+ \@@endchemicalpicture
+ \egroup
+ \ifnum\chemicaldrawingmode=1
+ \dimen0=\@@chemicalunit
+ \setbox0=\hbox{\lower\@@chemdepth\dimen0\box0}%
+ \ht0=\@@chemheight\dimen0
+ \dp0=\@@chemdepth\dimen0
+ \fi
+ \dimen0=\ht0
+ \advance\dimen0 by \dp0
+ \inchemicalfalse % enables \chemie{} in text
+ \setbox4=\alignedchemical\themidtext
+ \setbox6=\alignedchemical\thetoptext
+ \setbox8=\alignedchemical\thebottext
+ \setbox4=\hbox to \wd0
+ {\strut\hss$\vcenter{\box4}$\hss}%
+ \setbox2=\vbox to \dimen0
+ {\hbox to \wd0{\strut\hss\box6\hss}
+ \vfill
+ \hbox to \wd0{\strut\hss\box8\hss}
+ \vss}% disables the depth
+ \wd0=0pt \wd4=0pt
+ \ht2=\ht0 \dp2=\dp0
+ \ht4=\ht0 \dp4=\dp0
+ \@@chemicalborder{\box0\box4\box2}% text on top of chemicals
+ \endgroup
+ \ignorespaces
+ \egroup} % t.b.v. ungrouped floats
+
+\def\alignedchemical#1%
+ {\vtop
+ {\def\par{\egroup\hbox\bgroup\strut}%
+ \let\\=\par
+ \let\endgraf=\par
+ \hbox\bgroup\strut#1\egroup}}
+
+% \setchemicalcoordinates{#1}{#2}
+%
+% #1: verplaatsing in x-richting
+% #2: verplaatsing in y-richting
+
+\newif\ifchemicaldirection
+
+\def\checkchemicaldirection#1#2%
+ {\ifchemicaldirection
+ \ifnum#1>0 \advance\horchemical -\chemicaldirection \fi
+ \ifnum#1<0 \advance\horchemical +\chemicaldirection \fi
+ \ifnum#2>0 \advance\verchemical -\chemicaldirection \fi
+ \ifnum#2<0 \advance\verchemical +\chemicaldirection \fi
+ \chemicaldirectionfalse
+ \fi}
+
+\def\processchemicaldirection%
+ {\chemicaldirectiontrue\processchemicaltranslate}
+
+\def\setchemicalcoordinates#1#2%
+ {\advance\horchemical #1\relax
+ \advance\verchemical #2\relax
+ \checkchemicaldirection{#1}{#2}%
+ \!!counta=-\horchemical\edef\chemicalxoffset{\the\!!counta}%
+ \!!countb=-\verchemical\edef\chemicalyoffset{\the\!!countb}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at {\the\horchemical} {\the\verchemical}
+ \fi}
+
+\def\resetchemicalcoordinates
+ {\horchemical=0
+ \verchemical=0
+ \edef\chemicalxoffset{0}%
+ \edef\chemicalyoffset{0}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at 0 0
+ \fi}
+
+\def\restorechemicalcoordinates
+ {%\writestatus{ppchtex}{restoring \the\horchemical,\the\verchemical}%
+ \edef\chemicalxoffset{\the\horchemical}%
+ \edef\chemicalyoffset{\the\verchemical}%
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \setcoordinatesystem point at {\the\horchemical} {\the\verchemical}
+ \fi}
+
+\def\setchemicaltranslate #1 #2 #3
+ {\setvalue{\s!translate#1}{\setchemicalcoordinates{#2}{#3}}}
+
+\def\processchemicaltranslate#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{MOV#1}
+ {\ifnum##1=0
+ \def\chemicaloffset{0}% incompatible change
+ \resetchemicalcoordinates
+ \else
+ \getvalue{\s!translate##1}%
+ \dochemicaloffset{##1}%
+ \def\chemicaloffset{0}%
+ \fi}}%
+ \doprocess[#1]}
+
+\def\setchemicaldistance #1
+ {\setvalue{\s!distance1}{\setchemicalcoordinates{-#1}{ 0}}%
+ \setvalue{\s!distance2}{\setchemicalcoordinates{ 0}{ #1}}%
+ \setvalue{\s!distance3}{\setchemicalcoordinates{ #1}{ 0}}%
+ \setvalue{\s!distance4}{\setchemicalcoordinates{ 0}{-#1}}}
+
+\def\setchemicaldirection #1
+ {\def\chemicaldirection{#1}}
+
+\def\processchemicaldistance#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{ADJ#1}
+ {\ifnum##1=0
+ \resetchemicalcoordinates
+ \else
+ \def\@@chemicalpostponed{\getvalue{\s!distance##1}}%
+ \@@chemicalpostponed
+ \fi}}%
+ \doprocess[#1]}
+
+\def\setchemicalsubstitute #1
+ {\setvalue{\s!substitute1}{\setchemicalcoordinates{-#1}{ 0}}%
+ \setvalue{\s!substitute2}{\setchemicalcoordinates{ 0}{ #1}}%
+ \setvalue{\s!substitute3}{\setchemicalcoordinates{ #1}{ 0}}%
+ \setvalue{\s!substitute4}{\setchemicalcoordinates{ 0}{-#1}}}
+
+\def\processchemicalsubstitute#1%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{SUB#1}
+ {\ifnum##1=0
+ \resetchemicalcoordinates
+ \else
+ \def\@@chemicalpostponed{\getvalue{\s!substitute##1}}%
+ \@@chemicalpostponed
+ \fi}}%
+ \doprocess[#1]}
+
+% Het is mogelijk een offset of move meerdere malen uit te
+% voeren, door een nummer voor het commando te plaatsen.
+
+\def\chemicalrepeat {1}
+
+\def\redoprocesschemical[#1#2]%
+ {\doifelseinstring{#1}{0123456789.}
+ {\edef\chemicalrepeat{\chemicalrepeat#1}%
+ \redoprocesschemical[#2]}
+ {\processchemical[#1#2]%
+ \def\chemicalrepeat{1}}}
+
+\def\doprocesschemical[#1#2]#3%
+ {\doifelseinstring{#1}{0123456789.}
+ {\def\chemicalrepeat{#1}%
+ \redoprocesschemical[#2]}
+ {#3}}
+
+% \dochemicaloffset{#1}
+%
+% #1: binding
+
+\def\chemicaloffset{0}
+
+\def\processchemicaloffset#1%
+ {\dimen0=62500 sp % real calc on cardinals, funny number
+ \dimen0=\chemicalrepeat\dimen0
+ \divide\dimen0 by \@@localchemicalscale
+ \!!counta=\dimen0
+ \def\doprocess[##1##2]%
+ {\doifelseinstring{##1}{128}
+ {\edef\chemicaloffset{\the\!!counta}}
+ {\doifelseinstring{##1}{456}
+ {\edef\chemicaloffset{-\the\!!counta}}
+ {\doifelse{##1}{0}
+ {\edef\chemicaloffset{0}}
+ {\unknownchemical{OFF#1}}}}}%
+ \doprocess[#1]}
+
+\def\dochemicaloffset#1%
+ {\ifnum\chemicaloffset=0
+ \def\undochemicaloffset{}%
+ \else
+ \setchemicalcoordinates{-\chemicaloffset}{0}%
+ \def\undochemicaloffset%
+ {\setchemicalcoordinates{\chemicaloffset}{0}%
+ \def\undochemicaloffset{}}%
+ \fi}
+
+\def\processchemicalphantom#1#2%
+ {\setbox0=\hbox
+ {\def\splitoff##1????{##1}%
+ $\@@dochemicalstyle{\@@localchemicalformat\splitoff#2}$}%
+ \dimen0=.25\wd0
+ \divide\dimen0 by \@@localchemicalscale
+ \!!counta=\dimen0
+ \doifelseinstring{#1}{128}
+ {\edef\chemicaloffset{\the\!!counta}}
+ {\doifelseinstring{#1}{456}
+ {\edef\chemicaloffset{-\the\!!counta}}
+ {\doifelse{#1}{0}
+ {\edef\chemicaloffset{0}}
+ {\unknownchemical{OF#1:#2}}}}}
+
+% \dosetchemicalrotation{#1}{#2}
+%
+% #1: cos(phi)
+% #2: sin(phi)
+
+\def\chemicalrotation {1}
+\def\chemicalangle {0}
+\def\chemicalxoffset {0}
+\def\chemicalyoffset {0}
+
+\def\setchemicalmirror#1%
+ {\setvalue{\s!mirror#1}{*}}
+
+\def\resetchemicalmirror#1%
+ {\resetvalue{\s!mirror#1}}
+
+\def\togglechemicalmirror#1%
+ {\doifelse{\getvalue{\s!mirror#1}}{*}
+ {\resetchemicalmirror{#1}}
+ {\setchemicalmirror{#1}}}
+
+\def\setchemicalrotation #1 #2 #3 #4 #5 #6 #7 #8 #9
+ {\setvalue{\s!rotate1.#1}{\dosetchemicalrotation{#2}{#3}}%
+ \setvalue{\s!rotate2.#1}{\dosetchemicalrotation{#4}{#5}}%
+ \setvalue{\s!rotate3.#1}{\dosetchemicalrotation{#6}{#7}}%
+ \setvalue{\s!rotate4.#1}{\dosetchemicalrotation{#8}{#9}}}
+
+\def\setchemicalangle #1 #2 #3 #4 #5
+ {\setvalue{\s!angle1.#1}{\dosetchemicalangle{#2}}%
+ \setvalue{\s!angle2.#1}{\dosetchemicalangle{#3}}%
+ \setvalue{\s!angle3.#1}{\dosetchemicalangle{#4}}%
+ \setvalue{\s!angle4.#1}{\dosetchemicalangle{#5}}}
+
+\def\chemicalrotate[#1]%
+ {\doifelsedefined{\s!mirror#1}
+ {\getvalue{\s!rotate\chemicalrotation.#1\getvalue{\s!mirror#1}}%
+ \getvalue{\s!angle\chemicalrotation.#1\getvalue{\s!mirror#1}}}
+ {\getvalue{\s!rotate\chemicalrotation.#1}%
+ \getvalue{\s!angle\chemicalrotation.#1}}}
+
+\def\dosetchemicalangle#1% zwak zie onder
+ {\def\chemicalangle{#1}}
+
+\def\dosetchemicalrotation#1#2%
+ {\ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \startrotation by {#1} {#2} %% \stoprotation (t.b.v. testen)
+ \fi}
+
+\def\doresetchemicalrotation
+ {\ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \stoprotation
+ \fi}
+
+\def\processchemicalrotation#1%
+ {\def\doprocess[##1##2]%
+ {\doifelsenumber{##1}
+ {\def\chemicalrotation{##1}}
+ {\unknownchemical{ROT#1}}}%
+ \doprocess[#1]}
+
+% \filtertextelement[#1][#2][#3][#4]
+%
+% #1: volgnummer
+% #2: offset in uitlijningen
+% #3: lijst met uitlijningen -> \chemicalloca
+% #4: lijst met teksten -> \chemicaltext
+
+\def\setchemicallocation#1%
+ {\doifelse{#1}{}
+ {\edef\chemicalloca{c}}
+ {\edef\chemicalloca{#1}}}
+
+\newif\iffixedchemicaltext
+
+\def\filterchemicaltextelement[#1][#2][#3][#4]%
+ {\ifchemicaltextconstant
+ \def\chemicaltext{#4}%
+ \setchemicallocation{}%
+ \else
+ \ifnum#1=0\relax
+ \setchemicallocation{}%
+ \else
+ \iffixedchemicaltext
+ \!!counta#2
+ \else
+ \!!counta=\chemicalrotation
+ \advance\!!counta -1
+ \multiply\!!counta #2
+ \advance\!!counta #1
+ \fi
+ \getfromcommalist[#3][\the\!!counta]%
+ \setchemicallocation\commalistelement
+ \fi
+ \ifchemicalpicture
+ \let\chemicaltext\relax
+ \else
+ \advance\txtchemical 1
+ \getfromcommalist[#4][\txtchemical]%
+ \let\chemicaltext\commalistelement
+ \fi
+ \fi
+ \fixedchemicaltextfalse}
+
+% \putchemicaltext{#1}{#2}
+%
+% #1 : x-coordinaat
+% #2 : y-coordinaat
+%
+% \chemicaltext en \chemicalloca worden met \gettextelement
+% opgehaald uit de tweede set bij \chemie
+%
+% Ten behoeve van testdoeleinden wordt gebruik gemaakt van
+% \chemicalframe in plaats van het meer sjieke, maar tevens
+% meer trage \framed.
+
+\ifx\ruledhbox\undefined
+ \def\chemicalframe#1%
+ {\hbox
+ {\vrule\hskip-.4pt
+ \vbox{\hrule\vskip-.4pt\hbox{#1}\vskip-.4pt\hrule}%
+ \hskip-.4pt\vrule}}
+\else
+ \def\chemicalframe#1%
+ {\ruledhbox{#1}}
+\fi
+
+\def\doputchemicaltext#1 [#2] at #3 #4 %
+ {\ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[#2]{\chemicalangle}(#3,#4){#1}}}%
+ \else
+ \put {#1} [#2] at {#3} {#4} %
+ \fi}
+
+\def\dodoifsinglelocation#1#2\\#3%
+ {\ifx#2\relax#3\fi}
+
+\def\doifelsesinglelocation#1%
+ {\expandafter\dodoifsinglelocationelse#1\relax\\}
+
+\let\doifsinglelocationelse\doifelsesinglelocation
+
+\def\putchemicaltext#1#2%
+ {\enablechemicalspecials
+ \ifchemicalpicture
+ \setchemicalpicture{#1}{#2}%
+ \else
+ \doifelse\@@chemicaloption\v!test
+ {\def\@@chemicalframe{\chemicalframe}}
+ {\def\@@chemicalframe{}}%
+ \dosetsubscripts
+ \setbox2=\hbox{\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@localchemicalformat \chemicaltext}$}%
+ \setbox4=\hbox{$\@@dochemicalstyle{\@@localchemicalformat C\normalsubscript2\normapsuperscript2}$}%
+ \setbox6=\hbox{$\@@dochemicalstyle{\@@localchemicalformat O}$}% or C
+ \doresetsubscripts
+ \doifnot\@@chemicallocation\v!intext
+ {\ht2=\ht4
+ \dp2=\dp4}%
+ \setbox2=\hbox{\@@chemicalframe{\box2}}%
+ \ifdim\wd2>\wd6
+ \doifelse{#1}{0}
+ {\doifnot{#2}{0}{\wd2=\wd6}}
+ {%\doifsinglelocation\chemicalloca
+ {\doifinset{\chemicalloca}{t,b}{\wd2=\wd6}}}% common ?
+ \fi
+ \expanded
+ {\doputchemicaltext
+ {\noexpand\dowithchemical{\copy2}} % per se \copy2 i.p.v. \box2
+ [\chemicalloca] at {#1} {#2} }
+ \nomoreaccounting
+ \fi
+ \disablechemicalspecials}
+
+\def\setchemicaltextelement #1 #2 #3
+ {\setvalue{\s!chemicaltextelement#1}{\putchemicaltext{#2}{#3}}}
+
+\def\getchemicalfixedtextelement%
+ {\fixedchemicaltexttrue
+ \getchemicaltextelement}
+
+\def\getchemicaltextelement[#1][#2][#3][#4][#5]%
+ {\filterchemicaltextelement[#2][#3][#4][#5]%
+ \doifelse{#2}{0}
+ {\dochemicaloffset{#2}% % incompatible change
+ \putchemicaltext{0}{0}%
+ \undochemicaloffset} % incompatible change
+ {\chemicalrotate[#2]%
+ \dochemicaloffset{#2}%
+ \def\chemicaltextelementnumber{#2}%
+ \getvalue{\s!chemicaltextelement#1}%
+ \getvalue{\s!chemicaltextelement#11}%
+ \getvalue{\s!chemicaltextelement#12}%
+ \getvalue{\s!chemicaltextelement#13}%
+ \undochemicaloffset}}
+
+\def\processchemicaltextelement#1#2#3#4#5%
+ {\def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#1#2}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#1#2}
+ {\getchemicaltextelement[#1][##1][#4][#5][#3]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {\getchemicaltextelement[#1][##1][#4][#5][#3]%
+ \doifnot{##2}{?}{\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#2]%
+ \smallchemicaltextfalse}
+
+\def\processchemicalsmalltextelement%
+ {\smallchemicaltexttrue\processchemicaltextelement}
+
+\def\processchemicalsmalltextconstant%
+ {\smallchemicaltexttrue\processchemicaltextconstant}
+
+\def\processchemicalunrotatedtextelement#1#2#3#4#5#6%
+ {\bgroup
+ \xdef\@@xxx{0}%
+ \xdef\@@yyy{0}%
+ \def\putchemicaltext##1##2%
+ {\xdef\@@xxx{##1}%
+ \xdef\@@yyy{##2}}%
+ \getvalue{\s!chemicaltextelement#1}%
+ \egroup
+ \bgroup
+ \def\doputchemicaltext##1 [##2] at ##3 ##4 %
+ {\ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\rput{\chemicalangle}(\@@xxx,\@@yyy){\expanded{\rput[##2](##3,##4){##1}}}}%
+ \else
+ \put
+ {\stoprotation \setcoordinatesystem point at 0 0
+ \expanded{\put {##1} [##2] at {##3} {##4} }}
+ at {\@@xxx} {\@@yyy}
+ \fi}%
+ \processchemicaltextelement{#2}{#3}{#4}{#5}{#6}%
+ \egroup}
+
+\newif\ifchemicaltextconstant
+
+\def\processchemicaltextconstant#1#2#3#4%
+ {\chemicaltextconstanttrue
+ \let\@@oldchemicalframe\@@chemicalframe
+ \let\@@chemicalframe\relax
+ \processchemicaltextelement{#1}{#2}{#3}{#4}{}%
+ \let\@@chemicalframe\@@oldchemicalframe
+ \chemicaltextconstantfalse}
+
+% \plotchemicalline{#1}{#2}{#3}{#4}
+%
+% #1: x-coordinaat beginpunt
+% #2: y-coordinaat beginpunt
+% #3: x-coordinaat eindpunt
+% #4: y-coordinaat eindpunt
+
+\newconstant\chemicallinetype
+
+\def\doplotchemicalline
+ {\!!counte=\!!countc \advance\!!counte by -\!!counta
+ \!!countf=\!!countd \advance\!!countf by -\!!countb
+ \bgroup
+ \ifcase\chemicaldrawingmode
+ \ifcase\chemicallinetype
+ % 0 : normal line
+ \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /%
+ \or
+ % 1 : normal arrow
+ \arrow <5pt> [.2,.67] from {\!!counta} {\!!countb} to {\!!countc} {\!!countd}
+ \or
+ % 2 : reverse arrow
+ \arrow <5pt> [.2,.67] from {\!!countc} {\!!countd} to {\!!counta} {\!!countb}
+ \or
+ % 3 : unrotated line
+ \put {\stoprotation \setcoordinatesystem point at 0 0
+ \plot 0 0 {\!!counte} {\!!countf} /}
+ [\chemicallineposition] at {\!!counta} {\!!countb}
+ \else
+ % 4 : dashed line
+ \findlength {\plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /}%
+ \setdashesnear <2pt> for <\totalarclength>%
+ \plot {\!!counta} {\!!countb} {\!!countc} {\!!countd} /%
+ \fi
+ \or
+ \ifcase\chemicallinetype
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline{->}(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline{<-}(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \or
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[\chemicallineposition]{-\chemicalangle}%
+ (\!!counta,\!!countb){\psline(0,0)(\!!counte,\!!countf)}}}%
+ \else
+ \psset{linestyle=dashed}%
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(\!!counta,\!!countb)(\!!countc,\!!countd)}%
+ \fi
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ x3 := \MPdivten[\the\!!counte]u ;
+ y3 := \MPdivten[\the\!!countf]u ;
+ \ifcase\chemicallinetype
+ % 0 : normal line
+ draw ((z1--z2) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 1 : normal arrow
+ drawarrow ((z1--z2) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 2 : reverse arrow
+ drawarrow ((z2--z1) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \or
+ % 3 : unrotated line % nog \chemicalineposition: t/b
+ draw (origin--z3)
+ shifted (z1 rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \else
+ % 4 : dashed line
+ draw ((z1--z2) rotatedaround(origin,-\chemicalangle))
+ shifted z0 dashed dashpattern(on 5.5u off 6u) ;
+ \fi
+ \stopMPdrawing
+ \fi
+ \egroup
+ \account\!!counta\!!countb
+ \account\!!countc\!!countd}
+
+\def\plotchemicalline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \doplotchemicalline}
+
+\def\plotchemicalfactorline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifdim\@@chemicalfactor\onepoint=\onepoint \else
+ \scratchdimen\!!counta\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!counta\scratchdimen
+ \scratchdimen\!!countc\s!sp \multiply\scratchdimen1000 \scratchdimen\@@chemicalfactor\scratchdimen \divide\scratchdimen1000 \!!countc\scratchdimen
+ \fi
+ \doplotchemicalline}
+
+\def\plotchemicalzline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ filldraw ((
+ \ifnum\chemicalangle>180
+ z1--z2
+ \else\ifnum\chemicalangle<90
+ z1--(z2 shifted (-2u,+2u))--(z2 shifted (+2u,-2u))
+ \else\ifnum\chemicalangle=90
+ (z1 shifted (-2u,+2u))--(z1 shifted (+2u,-2u))--
+ (z2 shifted (+2u,+2u))--(z2 shifted (-2u,-2u))
+ \else
+ (z1 shifted (+2u,+2u))--(z1 shifted (-2u,-2u))--z2
+ \fi\fi\fi
+ --cycle) rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ \stopMPdrawing
+ \else
+ \doplotchemicalline
+ \ifnum\chemicalangle>180 \else
+ \ifnum\chemicalangle=90
+ \advance\!!counta by -20 \advance\!!countc by -20
+ \doplotchemicalline
+ \advance\!!counta by 40 \advance\!!countc by 40
+ \else\ifnum\chemicalangle<90
+ \advance\!!countc by -20 \advance\!!countd by +20
+ \doplotchemicalline
+ \advance\!!countc by +40 \advance\!!countd by -40
+ \else
+ \advance\!!counta by 20 \advance\!!countb by 20
+ \doplotchemicalline
+ \advance\!!counta by -40 \advance\!!countb by -40
+ \fi\fi
+ \fi
+ \doplotchemicalline
+ \fi}
+
+\def\plotchemicaldeltaline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ filldraw ((z1--(z2 rotatedaround(z1,5))--(z2 rotatedaround(z1,-5))
+ --cycle) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\setchemicallinesegment #1 #2 #3 #4 #5
+ {\setvalue{\s!chemicallinesegment#1}{\plotchemicalline{#2}{#3}{#4}{#5}}}
+
+\def\setchemicalfactorlinesegment #1 #2 #3 #4 #5
+ {\setvalue{\s!chemicallinesegment#1}{\plotchemicalfactorline{#2}{#3}{#4}{#5}}}
+
+\def\getchemicallinesegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \dochemicaloffset{#1}%
+ \getvalue{\s!chemicallinesegment#2}%
+ \getvalue{\s!chemicallinesegment#21}%
+ \getvalue{\s!chemicallinesegment#22}%
+ \undochemicaloffset}
+
+\def\getprivatechemicallinesegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \getvalue{\s!chemicallinesegment#2#1}}
+
+\def\doprocesschemicallinesegment#1#2#3#4#5%
+ {\chemicallinetype#1\relax
+ \def\chemicallineposition{#2}%
+ \def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#4#5}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#4#5}
+ {#3[##1][#4]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {#3[##1][#4]%
+ \doifnot{##2}{?}
+ {\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#5]}
+
+\def\processchemicallinesegment
+ {\doprocesschemicallinesegment0c\getchemicallinesegment}
+
+\def\processchemicalzlinesegment#1#2%
+ {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \bgroup
+ \def\plotchemicalline{\plotchemicalzline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicaldeltalinesegment#1#2%
+ {%\doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \bgroup
+ \def\plotchemicalline{\plotchemicaldeltaline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processprivatechemicallinesegment%
+ {\doprocesschemicallinesegment0c\getprivatechemicallinesegment}
+
+\def\processchemicaldownarrowsegment%
+ {\doprocesschemicallinesegment1c\getchemicallinesegment}
+
+\def\processchemicaluparrowsegment%
+ {\doprocesschemicallinesegment2c\getchemicallinesegment}
+
+\def\processchemicalunrotatedlinesegment#1%
+ {\doprocesschemicallinesegment3{#1}\getchemicallinesegment}
+
+\def\processchemicaldashedlinesegment
+ {\doprocesschemicallinesegment4c\getchemicallinesegment}
+
+\def\plotchemicaldasheddeltaline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ z20 = z2 rotatedaround(z1,+5) ;
+ z21 = z2 rotatedaround(z1,-5) ;
+ draw (z1 rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ save n ; n := 5 ;
+ for i=1 upto n :
+ draw ((((z20--z21) shifted -z2) shifted (i/n)[z2,z1])
+ rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ endfor
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\plotchemicalwavyline#1#2#3#4%
+ {\!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \ifnum\chemicaldrawingmode=2
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ save d ; pair d ;
+ d := z2 rotatedaround(z1,+5) shifted -z2 ;
+ save n ; n := 4 ;
+ draw ((for i=0 upto n-1 :
+ ((i)/n)[z1,z2] ..
+ ((i+.25)/n)[z1,z2] shifted d ..
+ ((i+.50)/n)[z1,z2] ..
+ ((i+.75)/n)[z1,z2] shifted -d ..
+ endfor
+ z2) rotatedaround(origin,-\chemicalangle)) shifted z0 ;
+ \stopMPdrawing
+ \account{#1}{#2}%
+ \account{#3}{#4}%
+ \else
+ \doplotchemicalline
+ \advance\!!countc by 16 \advance\!!countd by -21
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -8 \advance\!!countd by 14
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \advance\!!countc by -4 \advance\!!countd by 7
+ \doplotchemicalline
+ \fi}
+
+\def\processchemicaldasheddeltalinesegment#1#2%
+ {\bgroup
+ \def\plotchemicalline{\plotchemicaldasheddeltaline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicalwavylinesegment#1#2%
+ {\bgroup
+ \def\plotchemicalline{\plotchemicalwavyline}%
+ \doprocesschemicallinesegment0c\getchemicallinesegment{#1}{#2}%
+ \egroup}
+
+\def\processchemicalopenend#1#2%
+ {\doprocesschemicallinesegment0c\doprocesschemicalopenend{#1}{#2}}
+
+\def\doprocesschemicalopenend[#1][#2]%
+ {\chemicalrotate[#1]%
+ \dochemicaloffset{#1}%
+ \ifcase\chemicaldrawingmode
+ \beginpicture
+ \setquadratic\plot
+ 300 0 400 0
+ 500 0 550 75
+ 600 0 650 -75
+ 700 0 750 75
+ 800 0 850 -75
+ 900 0 950 0
+ 1050 0 /
+ \endpicture
+ \or
+ \rput{-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psline(300,0)(500,0)%
+ \rput(500,0){\psplot[yunit=75,plotstyle=curve]{0}{720}{x sin}}%
+ \psline(950,0)(1050,0)}%
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ draw
+ (((30.0u,0)--(50.0u,0){up}..(55.0u,7.5u)..
+ (60.0u,0)..(65.0u,-7.5u)..(70.0u,0)..
+ (75.0u,7.5u)..(80.0u,0)..(85.0u,-7.5u)..{up}
+ (90.0u,0)--(105.0u,0)) rotatedaround(origin,-\chemicalangle))
+ shifted z0 ;
+ \stopMPdrawing
+ \fi
+ \undochemicaloffset}
+
+% \plotchemicalcircle{#1}{#2}{#3}{#4}
+%
+% #1: lengte van de boog in graden
+% #2: x-coordinaat eindpunt
+% #3: y-coordinaat eindpunt
+
+\newif\ifchemicaldotted
+
+\def\plotchemicalcircle#1#2#3#4#5#6%
+ {\bgroup
+ \ifcase\chemicaldrawingmode
+ \ifchemicaldotted
+ \findlength{\circulararc {#4} degrees from {#5} {#6} center at {0} {0} }%
+ \divide\totalarclength by 6
+ \def\b{\the\totalarclength}%
+ \divide\totalarclength by 2
+ \def\a{\the\totalarclength}%
+ \setdashpattern <\a,\b,\b,\b,\b,\b,\a>
+ \fi
+ \circulararc {#4} degrees from {#5} {#6} center at {0} {0} %
+ \or
+ \ifchemicaldotted
+ \psset{linestyle=dashed}%
+ \fi
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\psarc(0,0){#3}{#1}{#2}}%
+ \or
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ r := \MPdivten[#3]*2u;
+ x0 := \MPdivten[\chemicalxoffset]u ;
+ y0 := \MPdivten[\chemicalyoffset]u ;
+ draw ((subpath (#1/45,#2/45) of (fullcircle scaled (r)))
+ rotatedaround (origin,\chemicalangle+150))
+ shifted z0 \ifchemicaldotted dashed withdots \fi ;
+ \stopMPdrawing
+ \fi
+ \egroup}
+
+\def\setchemicalcircsegment #1 #2 #3 #4 #5 #6 #7
+ {\setvalue{\s!chemicalcircsegment#1}{\plotchemicalcircle{#2}{#3}{#4}{#5}{#6}{#7}}}
+
+\def\getchemicalcircsegment[#1][#2]%
+ {\chemicalrotate[#1]%
+ \getvalue{\s!chemicalcircsegment#2}}
+
+\def\doprocesschemicalcircsegment#1#2%
+ {\def\doprocess[##1##2##3##4##5]%
+ {\doifelse{##1}{?}
+ {\doprocess[1..\maxchemical ????]}
+ {\doifchemicalnumber{##1}{#1#2}
+ {\doifelse{##2##3}{..}
+ {\doifchemicalnumber{##4}{#1#2}
+ {\getchemicalcircsegment[##1][#1]%
+ \doifnot{##1}{##4}
+ {\!!counta=##1\relax
+ \advance\!!counta by 1
+ \edef\nextsegment{\the\!!counta}%
+ \doprocess[\nextsegment..##4##5]}}}
+ {\getchemicalcircsegment[##1][#1]%
+ \doifnot{##2}{?}
+ {\doprocess[##2##3##4##5]}}}}}%
+ \doprocess[#2]}
+
+\def\processchemicalcircsegment%
+ {\chemicaldottedfalse\doprocesschemicalcircsegment}
+
+\def\processchemicaldottsegment%
+ {\chemicaldottedtrue\doprocesschemicalcircsegment}
+
+\let\endchemicalpicture = \relax
+\let\checkchemicalpicture = \relax
+\let\nomoreaccounting = \relax
+
+\newif\ifchemicalpicture
+
+\def\beginchemicalpicture#1% NO PSTRICKS SUPPORT YET
+ {\checkchemicalpicture
+ \bgroup % DOES NOT HANDLE AUTOWIDTH/HEIGHT
+ \chemicalpicturetrue
+ \processchemical[#1]}
+
+\def\setchemicalpicture#1#2%
+ {\chemicalpicturefalse
+ \def\endchemicalpicture%
+ {\@@endchemicallocalpicture{#1}{#2}%
+ \egroup
+ \ifnum\chemicaldrawingmode=1
+ \rput
+ {-\chemicalangle}(\chemicalxoffset,\chemicalyoffset)%
+ {\expanded{\rput[\chemicalloca]{\chemicalangle}(#1,#2){\box\nextbox}}}%
+ \else
+ \expanded{\put{\box\nextbox}[\chemicalloca] at {#1} {#2} }
+ \fi
+ \egroup}%
+ \def\checkchemicalpicture%
+ {\ifx\endchemicalpicture\relax \else
+ \writestatus{ppchtex}{missing end of picture (PE)}%
+ \endchemicalpicture
+ \fi}%
+ \setbox\nextbox=\hbox\bgroup
+ \@@beginchemicallocalpicture
+ % alternatief: gewoon accounting, en zelf l,r afhandelen
+ \ifnum\chemicaldrawingmode=1
+ % njet
+ \else
+ \accountingon
+ \let\nomoreaccounting=\accountingoff
+ \fi}
+
+\def\doskipchemical[#1][#2]%
+ {{\tt[ppchtex]}}
+
+\def\skipchemical%
+ {\dodoubleargument\doskipchemical}
+
+\def\complexchemical% met \expandafter
+ {\ifinchemical
+ \expandafter\dochemical
+ \else
+ \writestatus{ppchtex}{the [][]-alternative is not permitted here}%
+ \expandafter\skipchemical
+ \fi}
+
+\newif\ifinnerchemical
+
+\def\dosimplechemical#1#2#3%
+ {\doifelsedefined{\??chemical\c!location}
+ {\writestatus{ppchtex}{the {}{}-alternative is not permitted here}}
+ {\ifinnerchemical
+ \let\chemicalsign = \chemicalinnersign
+ \let\chemicalmolecule = \chemicalinnermolecule
+ \let\chemicalsinglearrow = \chemicalsingleinnerarrow
+ \let\chemicaldoublearrow = \chemicaldoubleinnerarrow
+ \let\chemicaltwintiparrow = \chemicaltwintipinnerarrow
+ \else
+ \let\chemicalsign = \chemicaloutersign
+ \let\chemicalmolecule = \chemicaloutermolecule
+ \let\chemicalsinglearrow = \chemicalsingleouterarrow
+ \let\chemicaldoublearrow = \chemicaldoubleouterarrow
+ \let\chemicaltwintiparrow = \chemicaltwintipouterarrow
+ \fi
+ \disablechemicalspecials
+ \processallactionsinset
+ [#1]
+ [ HIGH=>\sethighsubscripts,
+ LOW=>\setlowsubscripts,
+ PLUS=>\chemicalsign{+},
+ GIVES=>\chemicalsinglearrow{#2}{#3},
+ EQUILIBRIUM=>\chemicaldoublearrow{#2}{#3},
+ MESOMERIC=>\chemicaltwintiparrow{#2}{#3},
+ SINGLE=>\singlechemicalbond,
+ DOUBLE=>\doublechemicalbond,
+ TRIPLE=>\triplechemicalbond,
+ +=>\chemicalsign{+},
+ ->=>\chemicalsinglearrow{#2}{#3},
+ <->=>\chemicaldoublearrow{#2}{#3},
+ <>=>\chemicaltwintiparrow{#2}{#3},
+ -=>\singlechemicalbond,
+ --=>\doublechemicalbond,
+ ---=>\triplechemicalbond,
+ \s!unknown=>\enablechemicalspecials
+ \chemicalmolecule{\commalistelement}{#2}{#3}]}}
+
+\def\dosimplechemicalA#1#2#3% % evt: {#1,\relax}
+ {\let\chemicalspace=\relax
+ \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}%
+ \egroup}
+
+\def\dosimplechemicalB#1#2#3%
+ {\dosimplechemical{#1}{#2}{#3}%
+ \egroup}
+
+\def\dosimplechemicalC#1#2#3%
+ {$\simplechemical{#1}{#2}{#3}$%
+ \egroup} % erbij
+
+\def\simplechemical
+ {\ifinner
+ \innerchemicaltrue
+ \else
+ \innerchemicalfalse
+ \fi
+ \bgroup
+ \catcode`\^=\superscriptcatcode % t.b.v. \enableduplication
+ \catcode`\_=\subscriptcatcode % t.b.v. de zekerheid
+ \ifmmode
+ \ifinnerchemical
+ \def\next{\dotriplegroupempty\dosimplechemicalA}%
+ \else
+ \def\next{\dotriplegroupempty\dosimplechemicalB}%
+ \fi
+ \else
+ \def\next{\dotriplegroupempty\dosimplechemicalC}%
+ \fi
+ \next}
+
+\definecomplexorsimple\chemical
+
+\def\dogotochemical#1#2%
+ {\def\dowithchemical% % experiment
+ {\localgotochemical{#1}}% % experiment
+ \chemical} % experiment
+
+\def\gotochemical% % experiment
+ {\dosingleargument\dogotochemical} % experiment
+
+\def\dododochemical#1[#2][#3]% % experiment
+ {\def\simpledododochemical% % experiment
+ {#1[#2][#3]}% % experiment
+ \def\complexdododochemical[##1]% % experiment
+ {\def\dowithchemical% % experiment
+ {\localthisischemical{#2}}% % experiment
+ #1[#3][##1]}% % experiment
+ \complexorsimple\dododochemical} % experiment
+
+\def\dodochemical[#1][#2]%
+ {\ignorespaces
+ \ifinchemical
+ \drawchemical[#1][#2]%
+ \ignorespaces
+ \else
+ \startchemical[\c!location=\v!intext]%
+ \drawchemical[#1][#2]%
+ \expandafter\stopchemical
+ \fi
+ \ignorespaces}
+
+\def\dochemical[#1]%
+ {\def\simpledochemical%
+ {\@@writechemicalstate{ppchtex}{[#1][]}%
+ \dodochemical[#1][]}%
+ %
+ \def\complexdochemical[##1]%
+ {\@@writechemicalstate{ppchtex}{[#1][##1]}%
+ \txtchemical=0%
+ \dodochemical[#1][##1]}%
+ %
+ \def\complexdochemical[##1]% % experiment
+ {\@@writechemicalstate{ppchtex}{[#1][##1]}% % experiment
+ \txtchemical=0% % experiment
+ \dododochemical\dodochemical[#1][##1]}% % experiment
+ %
+ \complexorsimple\dochemical}
+
+% \processlocalchemicals{#1}
+%
+% #1: commando's
+
+\def\dodoprocesschemical#1%
+ {\processchemical[#1????]}
+
+\def\processlocalchemicals#1%
+ {\processcommalist[#1]\dodoprocesschemical}
+
+% \drawchemical[#1][#2]
+%
+% #1: bindingen enz.
+% #2: atomen enz.
+
+\def\localdodochemical[#1][#2]%
+ {\@@writechemicalstate{ppchtex}{[#1][#2]}%
+ %\bgroup % koppelen en afmetingen gaat fout, vandaar:
+ \advance\levchemical 1
+ \letvalue{\??chemical\s!unknown\the\levchemical}\unknownchemical
+ \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}%
+ \txtchemical=0
+ \dodochemical[#1][#2]%
+ % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname
+ \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname
+ \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname
+ \advance\levchemical -1
+ %\egroup
+ \ignorespaces}
+
+\def\drawchemical[#1][#2]%
+ {\ignorespaces
+ \def\dodochemical[##1][##2]%
+ {\drawchemical[##1][##2]%
+ \ignorespaces}%
+ \def\dochemical[##1]%
+ {\def\simpledochemical%
+ {\@@writechemicalstate{ppchtex}{[##1][#2]}%
+ \dodochemical[##1][#2]%
+ \ignorespaces}%
+ \def\complexdochemical[####1]%
+ {\dododochemical\localdodochemical[##1][####1,#2]}%
+ \complexorsimple\dochemical}%
+ \doif\@@chemicalstate\v!start
+ {\doifelse\chemicalname\s!unknown
+ {\getvalue{\s!executechemical\defaultchemical}[#2]}
+ {\getvalue{\s!executechemical\chemicalname}[#2]}%
+ \def\unknownchemical##1%
+ {\processunknownchemical[##1][#2]}%
+ \processcommalist[\@@chemicaloffset,#1]\dodoprocesschemical}%
+ \ignorespaces}
+
+\unexpanded\def\chemicaloxidation#1#2#3%
+ {\chemicaltop
+ {\ifnum#20=0
+ 0%
+ \else
+ #1\expandafter\uppercase\expandafter{\romannumeral#2}%
+ \fi}
+ {#3}}
+
+\def\chemicaltfraction{\ifinchemical.60\else.8\fi}
+\def\chemicalbfraction{\ifinchemical.45\else.6\fi}
+\def\chemicallfraction{\ifinchemical.1\else.1\fi}
+\def\chemicalrfraction{\ifinchemical.1\else.1\fi}
+
+\def\chemicaltighttext
+ {\def\chemicaltfraction{\ifinchemical.3\else.6\fi}%
+ \def\chemicalbfraction{\ifinchemical.2\else.4\fi}%
+ \def\chemicallfraction{\ifinchemical 0\else 0\fi}%
+ \def\chemicalrfraction{\ifinchemical 0\else 0\fi}}
+
+\def\dochemicaltop#1#2#3#4%
+ {\vbox
+ {\@@dochemicalcolor
+ \baselineskip=\chemicaltfraction\baselineskip \lineskip0pt
+ \halign
+ {#1###2\cr
+ $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr
+ $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr}}}
+
+\def\dochemicalbottom#1#2#3#4%
+ {\vtop
+ {\@@dochemicalcolor
+ \baselineskip=\chemicalbfraction\baselineskip \lineskip0pt
+ \halign
+ {#1###2\cr
+ $\@@dochemicalstyle{\@@currentchemicalformat#4}$\cr
+ $\@@dochemicalstyle{\scriptscriptstyle#3}$\cr}}}
+
+\def\chemicalleft#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\scriptscriptstyle#1}$%
+ $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}}
+
+\def\chemicalright#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$%
+ $\@@dochemicalstyle{\scriptscriptstyle#1}$}}
+
+\def\chemicalcentered#1%
+ {\setbox0=\hbox{$\@@dochemicalstyle{\scriptscriptstyle#1}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \dimen0=.5\ht2
+ \advance\dimen0 by -.5\ht0
+ \advance\dimen0 by \dp0
+ \hbox{\@@dochemicalcolor\raise\dimen0\box0}}
+
+\def\chemicalleftcentered#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ \chemicalcentered{#1}%
+ $\@@dochemicalstyle{\@@currentchemicalformat\hskip\chemicallfraction em#2}$}}
+
+\def\chemicalrightcentered#1#2%
+ {\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\@@currentchemicalformat#2\hskip\chemicalrfraction em}$%
+ \chemicalcentered{#1}}}
+
+\def\chemicaltop {\dochemicaltop \hss \hss }
+\def\chemicallefttop {\dochemicaltop \relax \hss }
+\def\chemicalrighttop {\dochemicaltop \hss \relax}
+\def\chemicalbottom {\dochemicalbottom \hss \hss }
+\def\chemicalleftbottom {\dochemicalbottom \relax \hss }
+\def\chemicalrightbottom {\dochemicalbottom \hss \relax}
+
+\def\chemicaltopleft #1{\chemicalleft {\chemicallefttop {#1}{}}}
+\def\chemicalbottomleft #1{\chemicalleft {\chemicalleftbottom{#1}{}}}
+\def\chemicaltopright #1{\chemicalright{\chemicallefttop {#1}{}}}
+\def\chemicalbottomright#1{\chemicalright{\chemicalleftbottom{#1}{}}}
+
+\def\chemicalsmashedleft#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \wd2=\wd0
+ \box2
+ \egroup}
+
+\def\chemicalsmashedmiddle#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \hbox{\hskip-.5\wd2\hskip.5\wd0\box2}
+ \egroup}
+
+\def\chemicalsmashedright#1%
+ {\hbox\bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat C}$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\@@currentchemicalformat#1}$}%
+ \hbox to \wd0{\hskip-\wd2\hskip\wd0\box2}%
+ \egroup}
+
+\def\+{\tabalign} % is \long in Plain
+
+\def\chemicalforever#1#2%
+ {\bgroup
+ \setbox0=\hbox
+ {\@@dochemicalcolor
+ $\@@dochemicalstyle{\scriptscriptstyle\hskip-.15em#2}$}%
+ \wd0=0pt
+ \big#1\normapsubscript{\hskip.1em\box0}%
+ \egroup}
+
+\def\disablechemicalspecials%
+ {\def\+##1{##1}\def\-##1{##1}%
+ \def\[{[}\def\]{]}%
+ \def\1{}\def\2{}\def\3{}\def\4{}\def\5{}\def\6{}\def\7{}%
+ \def\X{}%
+ \def\T{}\def\B{}\def\L{}\def\R{}\def\LC{}\def\RC{}%
+ \def\TL{}\def\BL{}\def\TR{}\def\BR{}%
+ \def\LT{}\def\LB{}\def\RT{}\def\RB{}%
+ \def\SL{}\def\SM{}\def\SR{}}
+
+\def\enablechemicalspecials%
+ {\def\+{\dodoublegroupempty\chemicaloxidation{+}}% {} needed!
+ \def\-{\dodoublegroupempty\chemicaloxidation{-}}% {} needed!
+ \def\[{\dodoublegroupempty\chemicalforever {[}}% {} needed!
+ \def\]{\dodoublegroupempty\chemicalforever {]}}% {} needed!
+ \def\1{\chemicaloxidation\relax1}%
+ \def\2{\chemicaloxidation\relax2}%
+ \def\3{\chemicaloxidation\relax3}%
+ \def\4{\chemicaloxidation\relax4}%
+ \def\5{\chemicaloxidation\relax5}%
+ \def\6{\chemicaloxidation\relax6}%
+ \def\7{\chemicaloxidation\relax7}%
+ \def\X{\chemicaltighttext}%
+ \def\T{\chemicaltop}%
+ \def\B{\chemicalbottom}%
+ \def\L{\chemicalleft}%
+ \def\LC{\chemicalleftcentered}%
+ \def\R{\chemicalright}%
+ \def\RC{\chemicalrightcentered}%
+ \def\TL{\chemicaltopleft}%
+ \def\BL{\chemicalbottomleft}%
+ \def\TR{\chemicaltopright}%
+ \def\BR{\chemicalbottomright}%
+ \def\LT{\chemicallefttop}%
+ \def\LB{\chemicalleftbottom}%
+ \def\RT{\chemicalrighttop}%
+ \def\RB{\chemicalrightbottom}%
+ \def\SL{\chemicalsmashedleft}%
+ \def\SM{\chemicalsmashedmiddle}%
+ \def\SR{\chemicalsmashedright}}
+
+% \reversechemical#1#2#3
+%
+% #1: prefix
+% #2: volgnummer enz
+% #3: tegengestelde volgnummers
+
+\def\reversechemical#1#2#3%
+ {\def\doprocess[##1##2]%
+ {\doifchemicalnumber{##1}{#1#2}%
+ {\getfromcommalist[#3][##1]%
+ \let\reversechemicalaction=\commalistelement
+ \processchemical[#1\reversechemicalaction##2]}}%
+ \doprocess[#2]}
+
+% \processunknownchemical[#1????][#2]
+%
+% #1: bindingen enz.
+% #2: atomen enz.
+
+\def\defaultchemical%
+ {SIX}
+
+\def\processunknownchemical[#1????][#2]%
+ {\processaction
+ [#1]
+ [ SAVE=>\executechemicalSAVE,
+ RESTORE=>\executechemicalRESTORE,
+ HIGH=>\sethighsubscripts,
+ LOW=>\setlowsubscripts,
+ \s!default=>,
+ \s!unknown=>\doifelsedefined{\s!executechemical#1}
+ {\def\chemicalrotation{1}%
+ \def\chemicaloffset{0}%
+ \doifdefined{\s!executechemical#1}
+ {\getvalue{\s!executechemical#1}[#2]}%
+ \@@chemicalpostponed}
+ {\getpredefinedchemical{#1}}]}
+
+\newcount\chemicalstack
+
+\setvalue{\s!chemical\c!x1}{0}
+\setvalue{\s!chemical\c!y1}{0}
+
+\def\executechemicalSAVE
+ {%\writestatus{ppchtex}{saving \the\horchemical,\the\verchemical}%
+ \advance\chemicalstack by 1
+ \letvalue {\s!chemical n\the\chemicalstack}=\chemicalname
+ %\letvalue {\s!chemical p\the\chemicalstack}=\@@chemicalpostponed
+ \setevalue{\s!chemical x\the\chemicalstack}{\the\horchemical}%
+ \setevalue{\s!chemical y\the\chemicalstack}{\the\verchemical}}
+
+\def\restorechemicalvalues#1%
+ {\let\oldprocesschemical=\processchemical
+ \doifdefined{\s!executechemical#1}{\getvalue{\s!executechemical#1}[]}%
+ \let\processchemical=\oldprocesschemical}
+
+\def\executechemicalRESTORE
+ {\ifnum\chemicalstack=0\relax
+ \horchemical=\getvalue{\s!chemical x1}\relax
+ \verchemical=\getvalue{\s!chemical y1}\relax
+ \else
+ \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}%
+ %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname
+ \let\@@chemicalpostponed=\relax
+ \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax
+ \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax
+ \advance\chemicalstack by -1
+ \fi
+ \restorechemicalcoordinates}
+
+% De onderstaande macro's zijn verantwoordelijk voor het zetten
+% van de + en pijlen. De +, en dus ook de pijlen, worden omhoog
+% gehaald. Dit oogt m.i. fraaier.
+
+\def\chemicalinnerclip#1%
+ {{\setbox0=\hbox{#1}\ht0\ht\strutbox\dp0\dp\strutbox\box0}}
+
+\def\chemicalraise#1#2%
+ {\chemicalinnerclip
+ {\setbox0=\hbox{$#1+$}%
+ \raise\dp0\hbox{$#1#2$}}}
+
+\def\chemicalinnersign#1% todo: \@@chemicaltextcolor
+ {\chemicalraise{\@@localchemicalstyle}{#1}}
+
+\def\chemicaloutersign#1%
+ {\chemicalraise{}{\@@dochemicalcolor#1}}
+
+\def\chemicalsingleinnerarrow#1#2%
+ {\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}
+
+\def\chemicaldoubleinnerarrow#1#2% todo: \@@chemicaltextcolor
+ {\chemicalinnerclip
+ {\lower.2ex\hbox
+ {\setbox0=\hbox{$\@@localchemicalstyle\longrightarrow$}%
+ \setbox2=\hbox{$\@@localchemicalstyle\longleftarrow$}%
+ \wd0=0pt\raise\ht0\box0\box2}}}
+
+\def\chemicaltwintipinnerarrow#1#2% todo: \@@chemicaltextcolor
+ {\chemicalinnerclip
+ {\setbox0=\hbox{\chemicalraise{\@@localchemicalstyle}{\longrightarrow}}%
+ \setbox2=\hbox{\chemicalraise{\@@localchemicalstyle}{\longleftarrow}}%
+ \wd0=0pt\box0\box2}}
+
+\def\dochemicalouterarrow#1#2#3%
+ {\bgroup
+ \setbox0=\hbox{$\longrightarrow$}%
+ \setbox2=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#2\quad}$}%
+ \setbox4=\hbox{$\@@dochemicalstyle{\scriptstyle\quad#3\quad}$}%
+ \dimen2=\wd0 % \dimen0 is used elsewhere
+ \ifdim\wd2>\dimen2 \dimen0=\wd2 \fi
+ \ifdim\wd4>\dimen2 \dimen0=\wd4 \fi
+ \chemicaloutermolecule
+ {#1}
+ {\ifdim\ht2>\zeropoint\box2\fi} % expands to \empty in test
+ {\ifdim\ht4>\zeropoint\box4\fi}% % expands to \empty in test
+ \egroup}
+
+\def\chemicalsingleouterarrow
+ {\dochemicalouterarrow
+ {\hbox to \dimen2{\rightarrowfill}}}
+
+\def\chemicaldoubleouterarrow
+ {\dochemicalouterarrow
+ {\lower.5\ht0\vbox
+ {\offinterlineskip
+ \hbox to \dimen2{\rightarrowfill}
+ \hbox to \dimen2{\leftarrowfill}}}}
+
+\def\chemicaltwintipouterarrow
+ {\dochemicalouterarrow
+ {\hbox
+ {\hbox to \dimen2{\rightarrowfill}%
+ \hskip-\dimen2
+ \hbox to \dimen2{\leftarrowfill}}}}
+
+\def\chemicalinnermolecule#1#2#3% no mathop here, can generate space
+ {\chemicalspace % todo: \@@chemicaltextcolor
+ \chemicalinnerclip
+ {\dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalstyle\strut#1}$%
+ \doresetsubscripts}%
+ \chemicalspace}
+
+\def\chemicaloutermolecule#1#2#3%
+ {\chemicalspace
+ \bgroup
+ \@@dochemicalcolor
+ \setbox0=\hbox % else the font is reset
+ {\dosetsubscripts
+ \hbox{$\@@dochemicalstyle{\strut#1}$}%
+ \doresetsubscripts}%
+ \mathop{\box0}%
+ \ifthirdargument
+ \doifnot{#2}{}{\normapsuperscript{\@@dochemicalstyle{\strut#2}}}%
+ \doifnot{#3}{}{\normapsubscript {\@@dochemicalstyle{\strut#3}}}%
+ \else
+ \doifnot{#2}{}
+ {\normapsubscript{\@@dochemicalstyle{\strut#2}}}%
+ \fi
+ \egroup
+ \chemicalspace}
+
+\def\chemicalsinglepicturearrow#1%
+ {\lower.5ex\hbox
+ {\@@dochemicalstyle
+ $\chemicalspace
+ \buildrel
+ \@@dochemicalstyle{\scriptstyle\quad#1\quad}%
+ \over{\overrightarrow
+ {\hphantom{\@chemicalstyle{\scriptstyle\quad#1\quad}}}}%
+ \chemicalspace$}}
+
+\def\chemicaldoublepicturearrow#1%
+ {\lower.5ex\hbox
+ {\@@dochemicalstyle
+ $\chemicalspace
+ \buildrel
+ \@@dochemicalstyle{\scriptstyle\quad#1\quad}%
+ \over{\overrightarrow{\overleftarrow
+ {\hphantom{\@@dochemicalstyle{\scriptstyle\quad#1\quad}}}}}%
+ \chemicalspace$}}
+
+% Bij de in-line bindingen wordt gebruik gemaakt van
+% een \hrule. De maatvoering wordt bepaald door een
+% kunstmatige em (\wd0).
+
+\def\somechemicalbond%
+ {\hrule width \wd0 height .4pt}
+
+\def\dochemicalbonds#1#2#3% todo: \@@chemicaltextstyle
+ {{\setbox0=\hbox
+ {${\@@localchemicalstyle M}$}%
+ \vbox to \ht0
+ {\@@dochemicalcolor
+ \hsize\wd0
+ \vskip.1\wd0#1\vfill#2\vfill#3\vskip.1\wd0}}}
+
+\def\singlechemicalbond%
+ {\dochemicalbonds{}{\somechemicalbond}{}}
+
+\def\doublechemicalbond%
+ {\dochemicalbonds{\somechemicalbond}{}{\somechemicalbond}}
+
+\def\triplechemicalbond%
+ {\dochemicalbonds{\somechemicalbond}{\somechemicalbond}{\somechemicalbond}}
+
+% In plaats van \def\naam{\chemie[...]...} kan beter gebruik
+% worden gemaakt van het commando
+%
+% \definieerchemie[naam]{commando's}
+%
+% De naam krijgt, om problemen met bestaande macro's te
+% voorkomen, een prefix. Bij het ophalen van een commando
+% worden beide definities afgehandeld.
+
+\def\dodefinechemical[#1]#2%
+ {\doifdefined{\??chemical#1}
+ {\writestatus{ppchtex}{chemical definition #1 is redefined}}%
+ \setvalue{\??chemical#1}{#2}}
+
+\unexpanded\def\definechemical%
+ {\dosingleargument\dodefinechemical}
+
+\def\getpredefinedchemical#1%
+ {\doifelsedefined{\??chemical#1}
+ {\getvalue{\??chemical#1}}
+ {\doifelsedefined{#1}
+ {\getvalue{#1}}
+ {\writestatus{ppchtex}{unknown chemical definition #1}}}}
+
+% Hieronder zijn de definities van de structuren opgenomen. De
+% naam van de structuur is als volgt opgebouwd:
+%
+% \executechemicalNUMBER[#1]
+%
+% waarbij [#1] betrekking heeft op de tekstelementen van \chemie,
+% de [tweede lijst] dus.
+%
+% De aan \chemie[#1][#2] meegegeven lijst van segmenten wordt
+% deels door de in \execute gedefinieerde macro's afgehandeld,
+% deels door algemene macro's. Segmenten hebben de vorm:
+%
+% [+|-|]identifier[X|XYZ|X..Y]
+%
+% Voorbeelden van segmenten zijn:
+%
+% R1
+% R1..4
+% R135
+% -R1
+% +R35
+
+\setchemicalmaximum 0
+
+\def\processchemical[#1]%
+ {\unknownchemical{#1}}
+
+\def\setchemicalname#1 %
+ {\def\chemicalname{#1}}
+
+\let\chemicalname=\s!unknown
+
+% Vooruitlopend op een gedetailleerde documentatie, zijn hier
+% vast enkele gebruikte afmetingen:
+%
+% lengte radikalen : 500
+% afstand radikalen : 100
+% afstand dubbele radikalen : 260
+% afstand substituenten : +125
+
+
+
+
+\def\executechemicalONE[#1]%
+ {\setchemicalname ONE
+ %
+ \setchemicalmaximum 8
+ \setchemicaldistance 0
+ \setchemicalsubstitute 625
+ \setchemicaldirection 303
+ %
+ \setchemicalrotation 1 1 0 1 0 1 0 1 0
+ \setchemicalrotation 2 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707
+ \setchemicalrotation 3 0 -1 0 -1 0 -1 0 -1
+ \setchemicalrotation 4 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707 -0.707
+ \setchemicalrotation 5 -1 0 -1 0 -1 0 -1 0
+ \setchemicalrotation 6 -0.707 0.707 -0.707 0.707 -0.707 0.707 -0.707 0.707
+ \setchemicalrotation 7 0 1 0 1 0 1 0 1
+ \setchemicalrotation 8 0.707 0.707 0.707 0.707 0.707 0.707 0.707 0.707
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 45 135 225 315
+ \setchemicalangle 3 90 180 270 0
+ \setchemicalangle 4 135 225 315 45
+ \setchemicalangle 5 180 270 0 90
+ \setchemicalangle 6 225 315 45 135
+ \setchemicalangle 7 270 0 90 180
+ \setchemicalangle 8 315 45 135 225
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 -1000 1000
+ \setchemicaltranslate 3 0 1000
+ \setchemicaltranslate 4 1000 1000
+ \setchemicaltranslate 5 1000 0
+ \setchemicaltranslate 6 1000 -1000
+ \setchemicaltranslate 7 0 -1000
+ \setchemicaltranslate 8 -1000 -1000
+ %
+ \setchemicallinesegment SB 300 0 700 0
+ \setchemicallinesegment DB1 300 50 700 50
+ \setchemicallinesegment DB2 300 -50 700 -50
+ %
+ %setchemicallinesegment EP 200 125 200 -125
+ \setchemicalfactorlinesegment EP 200 125 200 -125
+ %
+ \setchemicaltextelement ES 200 0
+ \setchemicaltextelement ED1 200 50
+ \setchemicaltextelement ED2 200 -50
+ \setchemicaltextelement ET1 200 75
+ \setchemicaltextelement ET2 200 0
+ \setchemicaltextelement ET3 200 -75
+ \setchemicaltextelement HB1 300 0
+ \setchemicaltextelement HB2 475 0
+ \setchemicaltextelement HB3 650 0
+ %
+ \setchemicaltextelement Z 800 0
+ \setchemicaltextelement RZ 950 0
+ \setchemicaltextelement ZN 500 0
+ \setchemicaltextelement ZTN 500 150
+ \setchemicaltextelement ZBN 500 -150
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\doprocesschemical[##1##2##3##4##5]
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ DIR##4##5=>\processchemicaldirection{##4##5},
+ OFF##4##5=>\processchemicaloffset{##4##5},
+ CCD##4##5=>\processchemicaldottsegment{CC}{##4##5},
+ LDD##4##5=>\processchemicaldashedlinesegment{DB1}{##4##5}%
+ \processchemicallinesegment{DB2}{##4##5},
+ RDD##4##5=>\processchemicallinesegment{DB1}{##4##5}%
+ \processchemicaldashedlinesegment{DB2}{##4##5},
+ OF##3:##5=>\processchemicalphantom{##3}{##5},
+ OE##3##4##5=>\processchemicalopenend{OE}{##3##4##5},
+ EP##3##4##5=>\processchemicallinesegment{EP}{##3##4##5},
+ ES##3##4##5=>\processchemicaltextconstant{ES}{##3##4##5}{\hbox{$\cdot$}}{0},
+ ED##3##4##5=>\processchemicaltextconstant{ED}{##3##4##5}{\hbox{$\cdot$}}{0},
+ ET##3##4##5=>\processchemicaltextconstant{ET}{##3##4##5}{\hbox{$\cdot$}}{0},
+ HB##3##4##5=>\processchemicaltextconstant{HB}{##3##4##5}{\hbox{$\cdot$}}{0},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ BB##3##4##5=>\processchemicaldeltalinesegment{SB}{##3##4##5},
+ BD##3##4##5=>\processchemicaldasheddeltalinesegment{SB}{##3##4##5},
+ BW##3##4##5=>\processchemicalwavylinesegment{SB}{##3##4##5},
+ SD##3##4##5=>\processchemicaldashedlinesegment{SB}{##3##4##5},
+ TB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5}%
+ \processchemicallinesegment{DB}{##3##4##5},
+ CZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{0}{},
+ ZTN##4##5=>\processchemicalsmalltextconstant{ZTN}{##4##5}{\chemicaltextelementnumber}{0},
+ ZTT##4##5=>\processchemicalsmalltextelement{ZTN}{##4##5}{#1}{0}{},
+ ZBN##4##5=>\processchemicalsmalltextconstant{ZBN}{##4##5}{\chemicaltextelementnumber}{0},
+ ZBT##4##5=>\processchemicalsmalltextelement{ZBN}{##4##5}{#1}{0}{},
+ ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0},
+ ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}
+ {l,l,t,r,r,r,b,l},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}}
+
+\def\executechemicalTHREE[#1]%
+ {\setchemicalname THREE
+ %
+ \setchemicalmaximum 3
+ \setchemicaldistance 289
+ \setchemicalsubstitute 952
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5
+ \setchemicalrotation 3 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 120 210 300 30
+ \setchemicalangle 3 240 330 60 150
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 0 1000
+ \setchemicaltranslate 3 1000 0
+ \setchemicaltranslate 4 0 -1000
+ %
+ \setchemicallinesegment B 577 0 -289 -500
+ \setchemicallinesegment SB 352 -130 -64 -370
+ \setchemicallinesegment -SB 352 -130 -289 -500
+ \setchemicallinesegment +SB 577 0 -64 -370
+ \setchemicallinesegment DB1 327 -87 -89 -327
+ \setchemicallinesegment DB2 377 -172 -39 -413
+ \setchemicallinesegment R 577 0 1077 0
+ \setchemicallinesegment -R 577 0 1010 250
+ \setchemicallinesegment +R 577 0 1010 -250
+ \setchemicallinesegment ER1 577 50 1077 50
+ \setchemicallinesegment ER2 577 -50 1077 -50
+ \setchemicallinesegment SR 837 0 1077 0
+ \setchemicallinesegment -SR 802 130 1010 250
+ \setchemicallinesegment +SR 802 -130 1010 -250
+ \setchemicallinesegment DR1 837 50 1077 50
+ \setchemicallinesegment DR2 837 -50 1077 -50
+ %
+ \setchemicaltextelement Z 577 0
+ \setchemicaltextelement RZ 1177 0
+ \setchemicaltextelement -RZ 1097 300
+ \setchemicaltextelement +RZ 1097 -300
+ \setchemicaltextelement CRZ 1077 0
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ ROT##4=>\processchemicalrotation{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{3}
+ {l,t,r, l,r,l, r,b,l, r,l,r},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{3}
+ {l,r,b, r,r,l, r,l,t, l,l,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}
+ {},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{3}
+ {l,r,r, t,r,l, r,l,l, b,l,r},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalFOUR[#1]%
+ {\setchemicalname FOUR
+ %
+ \setchemicalmaximum 4
+ \setchemicaldistance 500
+ \setchemicalsubstitute 0
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0 -1 -1 0 0 1 1 0
+ \setchemicalrotation 3 -1 0 0 1 1 0 0 -1
+ \setchemicalrotation 4 0 1 1 0 0 -1 -1 0
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 90 180 270 0
+ \setchemicalangle 3 180 270 0 90
+ \setchemicalangle 4 270 0 90 180
+ %
+ \setchemicaltranslate 1 -1000 0
+ \setchemicaltranslate 2 0 1000
+ \setchemicaltranslate 3 1000 0
+ \setchemicaltranslate 4 0 -1000
+ %
+ \setchemicallinesegment B 500 500 500 -500
+ \setchemicallinesegment SB 500 240 500 -240
+ \setchemicallinesegment -SB 500 240 500 -500
+ \setchemicallinesegment +SB 500 500 500 -240
+ \setchemicallinesegment DB1 450 240 450 -240
+ \setchemicallinesegment DB2 550 240 550 -240
+ \setchemicallinesegment EB 360 300 360 -300
+ \setchemicallinesegment R 500 500 854 854
+ \setchemicallinesegment -R 500 500 500 1000
+ \setchemicallinesegment +R 500 500 1000 500
+ \setchemicallinesegment ER1 465 535 819 889
+ \setchemicallinesegment ER2 535 465 889 819
+ \setchemicallinesegment SR 684 684 854 854
+ \setchemicallinesegment -SR 500 760 500 1000
+ \setchemicallinesegment +SR 760 500 1000 500
+ \setchemicallinesegment DR1 649 719 819 889
+ \setchemicallinesegment DR2 719 649 889 819
+ %
+ \setchemicaltextelement Z 500 500
+ \setchemicaltextelement RZ 925 925
+ \setchemicaltextelement -RZ 500 1100
+ \setchemicaltextelement +RZ 1100 500
+ \setchemicaltextelement CRZ 1038 1038
+ %
+ \setchemicaltextelement ZN 350 350
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ PB:##4=>\beginchemicalpicture{##4},
+ PE????=>\endchemicalpicture,
+ ROT##4=>\processchemicalrotation{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{4}
+ {b,l,t,r, l,t,r,b, t,r,b,l, r,b,l,t},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{4}
+ {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{},
+ ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0},
+ ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ EB##3##4=>\processchemicallinesegment{EB}{##3##4},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{4}
+ {lb,lt,rt,rb, lt,rt,rb,lb, rt,rb,lb,lt, rb,lb,lt,rt},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalFIVE[#1]%
+ {\setchemicalname FIVE
+ %
+ \setchemicalmaximum 5
+ \setchemicaldistance 688
+ \setchemicalsubstitute 1226
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0.309 -0.951 -0.951 -0.309 -0.309 0.940 0.951 0.309
+ \setchemicalrotation 3 -0.809 -0.588 -0.588 0.809 0.809 0.588 0.588 -0.809
+ \setchemicalrotation 4 -0.809 0.588 0.588 0.809 0.809 -0.588 -0.588 -0.809
+ \setchemicalrotation 5 0.309 0.951 0.951 -0.309 -0.309 -0.951 -0.951 0.309
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 72 162 252 342
+ \setchemicalangle 3 144 234 324 54
+ \setchemicalangle 4 216 306 36 126
+ \setchemicalangle 5 288 18 108 198
+ %
+ \setchemicaltranslate 1 -1376 0
+ \setchemicaltranslate 2 -425 1304
+ \setchemicaltranslate 3 1113 809
+ \setchemicaltranslate 4 1113 -809
+ \setchemicaltranslate 5 -425 -1304
+ %
+ \setchemicallinesegment A 1188 500 1188 -500
+ \setchemicallinesegment B 688 500 688 -500
+ \setchemicallinesegment S -263 808 688 -500
+ \setchemicallinesegment SS -116 606 541 -298
+ \setchemicallinesegment -SS -263 808 541 -298
+ \setchemicallinesegment +SS -116 606 688 -500
+ \setchemicallinesegment SB 688 240 688 -240
+ \setchemicallinesegment -SB 688 240 688 -500
+ \setchemicallinesegment +SB 688 500 688 -240
+ \setchemicallinesegment DB1 638 240 638 -240
+ \setchemicallinesegment DB2 738 240 738 -240
+ \setchemicallinesegment EB 548 340 548 -340
+ \setchemicallinesegment R 688 500 1093 794
+ \setchemicallinesegment -R 688 500 688 1000
+ \setchemicallinesegment +R 688 500 1163 345
+ \setchemicallinesegment ER1 659 540 1064 834
+ \setchemicallinesegment ER2 727 460 1122 754
+ \setchemicallinesegment SR 898 653 1093 794
+ \setchemicallinesegment -SR 688 760 688 1000
+ \setchemicallinesegment +SR 935 420 1163 345
+ \setchemicallinesegment DR1 869 693 1064 834
+ \setchemicallinesegment DR2 927 613 1122 754
+ %
+ \setchemicaltextelement Z 688 500
+ \setchemicaltextelement RZ 1188 863
+ \setchemicaltextelement -RZ 688 1100
+ \setchemicaltextelement +RZ 1258 315
+ \setchemicaltextelement CRZ 1323 947
+ %
+ \setchemicalcircsegment C -36 36 590 72 475 -345
+ \setchemicalcircsegment CC -72 0 590 72 182 -561
+ %
+ \setchemicaltextelement ZN 468 350
+ \setchemicaltextelement RN 860 625 % 1.25 Z
+ \setchemicaltextelement RTN 785 728 % .12 / 103 75
+ \setchemicaltextelement RBN 935 522
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [ FRONT????=>{\executechemicalFIVEFRONT[#1]},
+ PB:##4=>\beginchemicalpicture{##4},
+ PE????=>\endchemicalpicture,
+ ROT##4=>\processchemicalrotation{##4},
+ SUB##4=>\processchemicalsubstitute{##4},
+ ADJ##4=>\processchemicaldistance{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ -RZ##4=>\processchemicaltextelement{-RZ}{##4}{#1}{5}
+ {b,l,t,r,r, l,t,r,r,l, t,r,r,l,l, r,b,l,t,r},
+ +RZ##4=>\processchemicaltextelement{+RZ}{##4}{#1}{5}
+ {l,t,r,r,b, t,r,r,l,l, r,r,l,l,r, b,l,l,r,r},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ -SR##4=>\processchemicallinesegment{-SR}{##4},
+ +SR##4=>\processchemicallinesegment{+SR}{##4},
+ -RD##4=>\processchemicaldashedlinesegment{-R}{##4},
+ +RD##4=>\processchemicaldashedlinesegment{+R}{##4},
+ -RB##4=>\processchemicaldeltalinesegment{-R}{##4},
+ +RB##4=>\processchemicaldeltalinesegment{+R}{##4},
+ CRZ##4=>\processchemicaltextelement{CRZ}{##4}{#1}{0}{},
+ RTN##4=>\processchemicaltextconstant{RTN}{##4}{\chemicaltextelementnumber}{0},
+ RTT##4=>\processchemicaltextelement{RTN}{##4}{#1}{0}{},
+ RBN##4=>\processchemicaltextconstant{RBN}{##4}{\chemicaltextelementnumber}{0},
+ RBT##4=>\processchemicaltextelement{RBN}{##4}{#1}{0}{},
+ -SS##4=>\processchemicallinesegment{-SS}{##4},
+ +SS##4=>\processchemicallinesegment{+SS}{##4},
+ CCD##4=>\processchemicaldottsegment{CC}{##4},
+ SS##3##4=>\processchemicallinesegment{SS}{##3##4},
+ RD##3##4=>\processchemicaldashedlinesegment{R}{##3##4},
+ RB##3##4=>\processchemicaldeltalinesegment{R}{##3##4},
+ ZN##3##4=>\processchemicaltextconstant{ZN}{##3##4}{\chemicaltextelementnumber}{0},
+ ZT##3##4=>\processchemicaltextelement{ZN}{##3##4}{#1}{0}{},
+ RN##3##4=>\processchemicaltextconstant{RN}{##3##4}{\chemicaltextelementnumber}{0},
+ RT##3##4=>\processchemicaltextelement{RN}{##3##4}{#1}{0}{},
+ AU##3##4=>\processchemicaluparrowsegment{A}{##3##4},
+ AD##3##4=>\processchemicaldownarrowsegment{A}{##3##4},
+ CC##3##4=>\processchemicalcircsegment{CC}{##3##4},
+ CD##3##4=>\processchemicaldottsegment{C}{##3##4},
+ DB##3##4=>\processchemicallinesegment{DB}{##3##4},
+ DR##3##4=>\processchemicallinesegment{DR}{##3##4},
+ EB##3##4=>\processchemicallinesegment{EB}{##3##4},
+ ER##3##4=>\processchemicallinesegment{ER}{##3##4},
+ RZ##3##4=>\processchemicaltextelement{RZ}{##3##4}{#1}{5}
+ {l,l,r,r,r, l,r,r,b,l, r,r,b,l,t, r,l,l,t,r},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ SR##3##4=>\processchemicallinesegment{SR}{##3##4},
+ -R##3##4=>\processchemicallinesegment{-R}{##3##4},
+ +R##3##4=>\processchemicallinesegment{+R}{##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ C##2##3##4=>\processchemicalcircsegment{C}{##2##3##4},
+ R##2##3##4=>\processchemicallinesegment{R}{##2##3##4},
+ S##2##3##4=>\processchemicallinesegment{S}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalSIX[#1]%
+ {\setchemicalname SIX
+ %
+ \setchemicalmaximum 6
+ \setchemicalsubstitute 1375
+ \setchemicaldistance 866
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 0.5 -0.866 -0.866 -0.5 -0.5 0.866 0.866 0.5
+ \setchemicalrotation 3 -0.5 -0.866 -0.866 0.5 0.5 0.866 0.866 -0.5
+ \setchemicalrotation 4 -1 0 0 1 1 0 0 -1
+ \setchemicalrotation 5 -0.5 0.866 0.866 0.5 0.5 -0.866 -0.866 -0.5
+ \setchemicalrotation 6 0.5 0.866 0.866 -0.5 -0.5 -0.866 -0.866 0.5
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 60 150 240 330
+ \setchemicalangle 3 120 210 300 30
+ \setchemicalangle 4 180 270 0 90
+ \setchemicalangle 5 240 330 60 150
+ \setchemicalangle 6 300 30 120 210
+ %
+ \setchemicaltranslate 1 -1732 0
+ \setchemicaltranslate 2 -866 1500
+ \setchemicaltranslate 3 866 1500
+ \setchemicaltranslate 4 1732 0
+ \setchemicaltranslate 5 866 -1500
+ \setchemicaltranslate 6 -866 -1500
+ %
+ \setchemicallinesegment A 1386 500 1386 -500
+ \setchemicallinesegment S 0 1000 866 -500
+ \setchemicallinesegment SS 125 783 741 -283
+ \setchemicallinesegment -SS 0 1000 741 -283
+ \setchemicallinesegment +SS 125 783 866 -500
+ \setchemicallinesegment B 866 500 866 -500
+ \setchemicallinesegment SB 866 240 866 -240
+ \setchemicallinesegment -SB 866 240 866 -500
+ \setchemicallinesegment +SB 866 500 866 -240
+ \setchemicallinesegment DB1 816 240 816 -240
+ \setchemicallinesegment DB2 916 240 916 -240
+ \setchemicallinesegment EB 726 340 726 -340
+ \setchemicallinesegment R 866 500 1299 750
+ \setchemicallinesegment -R 866 500 866 1000
+ \setchemicallinesegment +R 866 500 1299 250
+ \setchemicallinesegment ER1 841 543 1274 793
+ \setchemicallinesegment ER2 891 457 1324 707
+ \setchemicallinesegment SR 1091 630 1299 750
+ \setchemicallinesegment -SR 866 740 866 1000
+ \setchemicallinesegment +SR 1091 370 1299 250
+ \setchemicallinesegment DR1 1066 673 1274 793
+ \setchemicallinesegment DR2 1116 588 1324 707
+ \setchemicallinesegment MID1 0 1000 -150 200
+ \setchemicallinesegment MID2 0 -1000 -150 -200
+ \setchemicallinesegment MIDS1 0 1000 -180 0
+ \setchemicallinesegment MIDS2 0 -1000 -180 0
+ %
+ \setchemicalcircsegment C -30 30 700 60 600 -346
+ \setchemicalcircsegment CC -60 0 700 60 350 -606
+ %
+ \setchemicaltextelement Z 866 500
+ \setchemicaltextelement RZ 1386 800
+ \setchemicaltextelement -RZ 866 1100
+ \setchemicaltextelement +RZ 1386 200
+ \setchemicaltextelement CRZ 1524 880
+ \setchemicaltextelement MIDZ -150 0
+ %
+ \setchemicaltextelement ZN 589 350
+ \setchemicaltextelement RN 1083 625 % 1.25 Z
+ \setchemicaltextelement RTN 1008 755 % .12 / 130 75
+ \setchemicaltextelement RBN 1158 495
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ FRONT????=>{\executechemicalSIXFRONT[#1]},
+ MID????=>\processchemicallinesegment{MID}{1????},
+ MIDS????=>\processchemicallinesegment{MIDS}{1????},
+ MIDZ????=>\processchemicaltextelement{MIDZ}{1????}{#1}{0}{},
+ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ ROT##4##5=>\processchemicalrotation{##4##5},
+ SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ -RZ##4##5=>\processchemicaltextelement{-RZ}{##4##5}{#1}{6}
+ {b,l,l,t,r,r, l,l,r,r,r,l, t,r,r,b,l,l, r,r,l,l,l,r},
+ +RZ##4##5=>\processchemicaltextelement{+RZ}{##4##5}{#1}{6}
+ {l,t,r,r,b,l, r,r,r,l,l,l, r,b,l,l,t,r, l,l,l,r,r,r},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ -SR##4##5=>\processchemicallinesegment{-SR}{##4##5},
+ +SR##4##5=>\processchemicallinesegment{+SR}{##4##5},
+ -RD##4##5=>\processchemicaldashedlinesegment{-R}{##4##5},
+ +RD##4##5=>\processchemicaldashedlinesegment{+R}{##4##5},
+ -RB##4##5=>\processchemicaldeltalinesegment{-R}{##4##5},
+ +RB##4##5=>\processchemicaldeltalinesegment{+R}{##4##5},
+ CRZ##4##5=>\processchemicaltextelement{CRZ}{##4##5}{#1}{0}{},
+ -SS##4##5=>\processchemicallinesegment{-SS}{##4##5},
+ +SS##4##5=>\processchemicallinesegment{+SS}{##4##5},
+ CCD##4##5=>\processchemicaldottsegment{CC}{##4##5},
+RTN##4##5=>\processchemicaltextconstant{RTN}{##4##5}{\chemicaltextelementnumber}{0},
+RTT##4##5=>\processchemicaltextelement{RTN}{##4##5}{#1}{0}{},
+RBN##4##5=>\processchemicaltextconstant{RBN}{##4##5}{\chemicaltextelementnumber}{0},
+RBT##4##5=>\processchemicaltextelement{RBN}{##4##5}{#1}{0}{},
+ SS##3##4##5=>\processchemicallinesegment{SS}{##3##4##5},
+ RD##3##4##5=>\processchemicaldashedlinesegment{R}{##3##4##5},
+ RB##3##4##5=>\processchemicaldeltalinesegment{R}{##3##4##5},
+ ZN##3##4##5=>\processchemicaltextconstant{ZN}{##3##4##5}{\chemicaltextelementnumber}{0},
+ ZT##3##4##5=>\processchemicaltextelement{ZN}{##3##4##5}{#1}{0}{},
+RN##3##4##5=>\processchemicaltextconstant{RN}{##3##4##5}{\chemicaltextelementnumber}{0},
+RT##3##4##5=>\processchemicaltextelement{RN}{##3##4##5}{#1}{0}{},
+ AU##3##4##5=>\processchemicaluparrowsegment{A}{##3##4##5},
+ AD##3##4##5=>\processchemicaldownarrowsegment{A}{##3##4##5},
+ CD##3##4##5=>\processchemicaldottsegment{C}{##3##4##5},
+ CC##3##4##5=>\processchemicalcircsegment{CC}{##3##4##5},
+ DB##3##4##5=>\processchemicallinesegment{DB}{##3##4##5},
+ EB##3##4##5=>\processchemicallinesegment{EB}{##3##4##5},
+ ER##3##4##5=>\processchemicallinesegment{ER}{##3##4##5},
+ RZ##3##4##5=>\processchemicaltextelement{RZ}{##3##4##5}{#1}{6}
+ {l,l,t,r,r,b, l,r,r,r,l,l, r,r,b,l,l,t, r,l,l,l,r,r},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ SR##3##4##5=>\processchemicallinesegment{SR}{##3##4##5},
+ DR##3##4##5=>\processchemicallinesegment{DR}{##3##4##5},
+ -R##3##4##5=>\processchemicallinesegment{-R}{##3##4##5},
+ +R##3##4##5=>\processchemicallinesegment{+R}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ C##2##3##4##5=>\processchemicalcircsegment{C}{##2##3##4##5},
+ R##2##3##4##5=>\processchemicallinesegment{R}{##2##3##4##5},
+ S##2##3##4##5=>\processchemicallinesegment{S}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalSEVEN[#1]% incomplete !
+ {\setchemicalname SEVEN
+ %
+ \setchemicalmaximum 7
+ \setchemicalsubstitute -
+ \setchemicaldistance 1038
+ %
+ \setchemicalrotation 1 .623 .782 - - - - - -
+ \setchemicalrotation 2 -.223 .975 - - - - - -
+ \setchemicalrotation 3 -.901 .434 - - - - - -
+ \setchemicalrotation 4 -.901 -.434 - - - - - -
+ \setchemicalrotation 5 -.223 -.975 - - - - - -
+ \setchemicalrotation 6 .623 -.782 - - - - - -
+ \setchemicalrotation 7 1 0 - - - - - -
+ %
+ \setchemicalangle 1 0 - - -
+ \setchemicalangle 2 51.429 - - -
+ \setchemicalangle 3 102.857 - - -
+ \setchemicalangle 4 154.286 - - -
+ \setchemicalangle 5 205.714 - - -
+ \setchemicalangle 6 257.143 - - -
+ \setchemicalangle 7 308.571 - - -
+ %
+ \setchemicaltranslate 1 - -
+ \setchemicaltranslate 2 - -
+ \setchemicaltranslate 3 - -
+ \setchemicaltranslate 4 - -
+ \setchemicaltranslate 5 - -
+ \setchemicaltranslate 6 - -
+ \setchemicaltranslate 7 - -
+ %
+ \setchemicallinesegment B 1038 500 1038 -500
+ \setchemicallinesegment SB 1038 240 1038 -240
+ \setchemicallinesegment -SB 1038 240 1038 -500
+ \setchemicallinesegment +SB 1038 500 1038 -240
+ %
+ \setchemicaltextelement Z 1038 500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ %ROT##4##5=>\processchemicalrotation{##4},
+ %SUB##4##5=>\processchemicalsubstitute{##4##5},
+ %ADJ##4##5=>\processchemicaldistance{##4##5},
+ %MOV##4##5=>\processchemicaltranslate{##4##5},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalEIGHT[#1]% incomplete !
+ {\setchemicalname EIGHT
+ %
+ \setchemicalmaximum 8
+ %\setchemicalsubstitute 1307
+ \setchemicaldistance 1207
+ %
+ \setchemicalrotation 1 .707 .707 - - - - - -
+ \setchemicalrotation 2 0 1 - - - - - -
+ \setchemicalrotation 3 -.707 .707 - - - - - -
+ \setchemicalrotation 4 -1 0 - - - - - -
+ \setchemicalrotation 5 -.707 -.707 - - - - - -
+ \setchemicalrotation 6 0 -1 - - - - - -
+ \setchemicalrotation 7 .707 -.707 - - - - - -
+ \setchemicalrotation 8 1 0 - - - - - -
+ %
+ \setchemicalangle 1 45 - - -
+ \setchemicalangle 2 90 - - -
+ \setchemicalangle 3 135 - - -
+ \setchemicalangle 4 180 - - -
+ \setchemicalangle 5 225 - - -
+ \setchemicalangle 6 270 - - -
+ \setchemicalangle 7 315 - - -
+ \setchemicalangle 8 0 - - -
+ %
+ \setchemicaltranslate 1 -2414 0
+ \setchemicaltranslate 2 -1706 1706
+ \setchemicaltranslate 3 0 2414
+ \setchemicaltranslate 4 1706 1706
+ \setchemicaltranslate 5 2414 0
+ \setchemicaltranslate 6 1706 -1706
+ \setchemicaltranslate 7 0 -2414
+ \setchemicaltranslate 8 -1706 -1706
+ %
+ \setchemicallinesegment B 1207 500 1207 -500
+ \setchemicallinesegment SB 1207 240 1207 -240
+ \setchemicallinesegment -SB 1207 240 1207 -500
+ \setchemicallinesegment +SB 1207 500 1207 -240
+ %
+ \setchemicaltextelement Z 1207 500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ PB:##4##5=>\beginchemicalpicture{##4##5},
+ PE????=>\endchemicalpicture,
+ %SUB##4##5=>\processchemicalsubstitute{##4##5},
+ ADJ##4##5=>\processchemicaldistance{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ -SB##4##5=>\processchemicallinesegment{-SB}{##4##5},
+ +SB##4##5=>\processchemicallinesegment{+SB}{##4##5},
+ SB##3##4##5=>\processchemicallinesegment{SB}{##3##4##5},
+ B##2##3##4##5=>\processchemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalFIVEFRONT[#1]%
+ {\executechemicalFIVE[]%
+ %
+ \setchemicalname FIVEFRONT
+ %
+ \setchemicallinesegment -R 688 500 688 100
+ \setchemicallinesegment +R 688 500 688 900
+ %
+ \setchemicaltextelement -RZ 0 -1300
+ \setchemicaltextelement +RZ 0 1300
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\def\chemicalrotation{2}%
+ \processaction
+ [##1##2##3##4]
+ [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{5}
+ {,,,,, t,t,t,t,t},
+ +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{5}
+ {,,,,, b,b,b,b,b},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4},
+ +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4},
+ BB##3##4=>\processchemicalzlinesegment{B}{##3##4},
+ R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}%
+ \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalSIXFRONT[#1]%
+ {\executechemicalSIX[]%
+ %
+ \setchemicalname SIXFRONT
+ %
+ \setchemicallinesegment -R 866 500 866 100
+ \setchemicallinesegment +R 866 500 866 900
+ %
+ \setchemicaltextelement -RZ 0 -1300
+ \setchemicaltextelement +RZ 0 1300
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\def\chemicalrotation{2}%
+ \processaction
+ [##1##2##3##4]
+ [ -RZ##4=>\processchemicalunrotatedtextelement{Z}{-RZ}{##4}{#1}{6}
+ {,,,,,, t,t,t,t,t,t},
+ +RZ##4=>\processchemicalunrotatedtextelement{Z}{+RZ}{##4}{#1}{6}
+ {,,,,,, b,b,b,b,b,b},
+ -SB##4=>\processchemicallinesegment{-SB}{##4},
+ +SB##4=>\processchemicallinesegment{+SB}{##4},
+ SB##3##4=>\processchemicallinesegment{SB}{##3##4},
+ -R##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##3##4},
+ +R##3##4=>\processchemicalunrotatedlinesegment{b}{+R}{##3##4},
+ BB##3##4=>\processchemicalzlinesegment{B}{##3##4},
+ R##2##3##4=>\processchemicalunrotatedlinesegment{t}{-R}{##2##3##4}%
+ \processchemicalunrotatedlinesegment{b}{+R}{##2##3##4},
+ B##2##3##4=>\processchemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\processchemicaltextelement{Z}{##2##3##4}{#1}{0}{},
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+% 1 : 0
+% 2 : -115
+% 3* : -195
+% 3 : -165
+% 4 : -245
+
+\def\executechemicalCARBON[#1]%
+ {\setchemicalname CARBON
+ %
+ \setchemicalmaximum 4
+ \setchemicaldistance 0
+ \setchemicalsubstitute 0
+ %
+ \setchemicalrotation 1 1 0 0 -1 -1 0 0 1
+ \setchemicalrotation 2 -0.423 -0.906 -0.906 0.423 0.423 0.906 0.906 -0.423
+ \setchemicalrotation 3 -0.966 -0.259 -0.259 0.966 0.966 0.259 0.259 -0.966
+ \setchemicalrotation 3* -0.966 0.259 0.259 0.966 0.966 -0.259 -0.259 -0.966
+ \setchemicalrotation 4 -0.423 0.906 0.906 0.423 0.423 -0.906 -0.906 -0.423
+ %
+ \setchemicalangle 1 0 90 180 270
+ \setchemicalangle 2 115 205 295 25
+ \setchemicalangle 3 165 255 345 75
+ \setchemicalangle 3* 195 285 15 105
+ \setchemicalangle 4 245 335 65 155
+ %
+ \setchemicaltranslate 1 -1500 0
+ \setchemicaltranslate 2 0 1500
+ \setchemicaltranslate 3 1500 0
+ \setchemicaltranslate 4 0 -1500
+ %
+ \setchemicallinesegment B1 500 0 1000 0
+ \setchemicallinesegment B2 300 0 1000 0
+ \setchemicallinesegment B3 500 0 1000 0
+ \setchemicallinesegment B4 300 0 1000 0
+ %
+ \setchemicaltextelement Z 1100 0
+ %
+ \setchemicalcircsegment C 0 360 500 360 0 -500
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\processaction
+ [##1##2##3##4##5]
+ [ MIR????=>\setchemicalmirror{3},
+ -MIR????=>\resetchemicalmirror{3},
+ *MIR????=>\togglechemicalmirror{3},
+ CB????=>\processlocalchemicals{B,C,Z},
+ C????=>\processchemicalcircsegment{C}{1????},
+ -ROT##5=>\reversechemical{ROT}{##5}{3,4,1,2},
+ ROT##4##5=>\processchemicalrotation{##4##5},
+ MOV##4##5=>\processchemicaltranslate{##4##5},
+ CB##3##4##5=>\processlocalchemicals
+ {ROT##3,C,B,Z2..4,
+ MOV##3,*MIR,-ROT##3,C,B,Z2..4},
+ B##2##3##4##5=>\processprivatechemicallinesegment{B}{##2##3##4##5},
+ Z##2##3##4##5=>\processchemicaltextelement{Z}{##2##3##4##5}{#1}{4}
+ {l,t,r,b, t,r,b,l, r,b,l,t, b,l,t,r},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+% 1: 45 2: -90 3: -225
+% 4: -45 5: -135 6: -270
+
+\newif\ifNEWMANstagger \NEWMANstaggertrue
+
+\def\executechemicalNEWMANSTAGGER%
+ {\NEWMANstaggertrue\executechemicalNEWMAN}
+
+\def\executechemicalNEWMANECLIPSE%
+ {\NEWMANstaggerfalse\executechemicalNEWMAN}
+
+\def\executechemicalNEWMAN[#1]%
+ {\setchemicalname NEWMAN
+ %
+ \setchemicalmaximum 6
+ \setchemicaldistance 0
+ \setchemicalsubstitute 0
+ %
+ \ifNEWMANstagger
+ \setchemicalrotation 1 0.707 0.707 0.707 -0.707 -0.707 -0.707 -0.707 0.707
+ \setchemicalrotation 2 0 -1 -1 0 0 1 1 0
+ \setchemicalrotation 3 -0.707 0.707 0.707 0.707 0.707 -0.707 -0.707 -0.707
+ \else
+ \setchemicalrotation 1 .866 -.5 -.5 -.866 -.866 .5 .5 .866
+ \setchemicalrotation 2 -.259 .966 .966 .259 .259 -.966 -.966 -.259
+ \setchemicalrotation 3 -.5 -.866 -.866 .5 .5 .866 .866 -.5
+ \fi
+ \setchemicalrotation 4 0.707 -0.707 -0.707 -0.707 -0.707 0.707 0.707 0.707
+ \setchemicalrotation 5 -0.707 -0.707 -0.707 0.707 0.707 0.707 0.707 -0.707
+ \setchemicalrotation 6 0 1 1 0 0 -1 -1 0
+ %
+ \ifNEWMANstagger
+ \setchemicalangle 1 315 45 135 225
+ \setchemicalangle 2 90 180 270 0
+ \setchemicalangle 3 225 315 45 135
+ \else
+ \setchemicalangle 1 30 120 210 300
+ \setchemicalangle 2 255 345 75 165
+ \setchemicalangle 3 120 210 300 30
+ \fi
+ \setchemicalangle 4 45 135 225 315
+ \setchemicalangle 5 135 225 315 45
+ \setchemicalangle 6 270 0 90 180
+ %
+ \setchemicaltranslate 1 -1500 0
+ \setchemicaltranslate 2 0 1500
+ \setchemicaltranslate 3 1500 0
+ \setchemicaltranslate 4 0 -1500
+ %
+ \setchemicallinesegment B1 0 0 1000 0
+ \setchemicallinesegment B2 0 0 1000 0
+ \setchemicallinesegment B3 0 0 1000 0
+ \setchemicallinesegment B4 500 0 1000 0
+ \setchemicallinesegment B5 500 0 1000 0
+ \setchemicallinesegment B6 500 0 1000 0
+ %
+ \setchemicaltextelement Z 1100 0
+ %
+ \setchemicalcircsegment C 0 360 500 360 0 -500
+ %
+ \def\processchemical[##1##2##3##4]%
+ {\processaction
+ [##1##2##3##4]
+ [STAGGER????=>{\executechemicalNEWMANSTAGGER[#1]},
+ ECLIPSE????=>{\executechemicalNEWMANECLIPSE[#1]},
+ B????=>\processlocalchemicals{B1..6},
+ CB????=>\processlocalchemicals{B1..6,C,Z1..6},
+ C????=>\processchemicalcircsegment{C}{1????},
+ ROT##4=>\processchemicalrotation{##4},
+ MOV##4=>\processchemicaltranslate{##4},
+ B##2##3##4=>\processprivatechemicallinesegment{B}{##2##3##4},
+ Z##2##3##4=>\ifNEWMANstagger
+ \processchemicaltextelement{Z}{##2##3##4}{#1}{6}
+ {l,t,r,l,r,b, l,r,l,r,r,l, r,b,l,r,l,t, r,l,r,l,l,r}%
+ \else
+ \processchemicaltextelement{Z}{##2##3##4}{#1}{6}
+ {l,r,t,t,r,b, t,b,r,r,b,l, r,l,b,b,l,t, b,t,l,l,t,r}%
+ \fi,
+ \s!unknown=>\unknownchemical{##1##2##3##4}]}}
+
+\def\executechemicalCHAIR[#1]% smaller
+ {\setchemicalname CHAIR
+ %
+ \setchemicalmaximum 6
+ %
+ \setchemicallinesegment B1 1600 800 2800 -800
+ \setchemicallinesegment B2 2800 -800 800 0
+ \setchemicallinesegment B3 800 0 -1600 -800
+ \setchemicallinesegment B4 -1600 -800 -2800 800
+ \setchemicallinesegment B5 -2800 800 -800 0
+ \setchemicallinesegment B6 -800 0 1600 800
+ %
+ \setchemicallinesegment +R1 1600 800 1600 1600
+ \setchemicallinesegment +R2 2800 -800 2800 -1600
+ \setchemicallinesegment +R3 800 0 800 800
+ \setchemicallinesegment +R4 -1600 -800 -1600 -1600
+ \setchemicallinesegment +R5 -2800 800 -2800 1600
+ \setchemicallinesegment +R6 -800 0 -800 -800
+ %
+ \setchemicallinesegment -R1 1600 800 2350 522 % 750 278
+ \setchemicallinesegment -R2 2800 -800 3493 -400
+ \setchemicallinesegment -R3 800 0 1329 -600 % 528 600
+ \setchemicallinesegment -R4 -1600 -800 -2350 -522 % 750 278
+ \setchemicallinesegment -R5 -2800 800 -3493 400
+ \setchemicallinesegment -R6 -800 0 -1329 600 % 528 600
+ %
+ \setchemicaltextelement +RZ1 1600 1800
+ \setchemicaltextelement +RZ2 2800 -1800
+ \setchemicaltextelement +RZ3 800 1000
+ \setchemicaltextelement +RZ4 -1600 -1800
+ \setchemicaltextelement +RZ5 -2800 1800
+ \setchemicaltextelement +RZ6 -800 -1000
+ %
+ \setchemicaltextelement -RZ1 2538 453 % 200 lang
+ \setchemicaltextelement -RZ2 3666 -300
+ \setchemicaltextelement -RZ3 1460 -750
+ \setchemicaltextelement -RZ4 -2538 -453
+ \setchemicaltextelement -RZ5 -3666 300
+ \setchemicaltextelement -RZ6 -1460 750
+ %
+ \def\processchemical[##1##2##3##4##5]%
+ {\def\chemicalrotation{1}%
+ \processaction
+ [##1##2##3##4##5]
+ [ B????=>\processlocalchemicals{B1,B2,B3,B4,B5,B6},
+ -R????=>\processlocalchemicals{-R1,-R2,-R3,-R4,-R5,-R6},
+ +R????=>\processlocalchemicals{+R1,+R2,+R3,+R4,+R5,+R6},
+ B##2????=>{\getchemicallinesegment[0][B##2]},
+ -RZ##4????=>{\getchemicalfixedtextelement[-RZ##4][1][##4][l,l,tc,r,r,bc][#1]},
+ +RZ##4????=>{\getchemicalfixedtextelement[+RZ##4][1][##4][c][#1]},
+ -R##3????=>{\getchemicallinesegment[0][-R##3]},
+ +R##3????=>{\getchemicallinesegment[0][+R##3]},
+ \s!unknown=>\unknownchemical{##1##2##3##4##5}]}}
+
+\def\executechemicalarrow#1#2[#3]%
+ {\dogetcommalistelement1\from#3\to\toptext
+ \dogetcommalistelement2\from#3\to\bottext
+ \def\dochemicaltext##1%
+ {\dosetsubscripts%
+ $\@@dochemicalstyle{\@@localchemicalformat\strut##1}$%
+ \doresetsubscripts}%
+ \doifelse\@@chemicallocation\v!intext
+ {#1{\dochemicaltext\toptext}}%
+ {\setbox\chemicalsymbols=\hbox
+ {\box\chemicalsymbols
+ \vbox{\halign{##\cr
+ \hbox to 3em{\hss\dochemicaltext{\toptext}\hss}\cr
+ #2%
+ \hbox to 3em{\hss\dochemicaltext{\bottext}\hss}\cr}}}}}
+
+\def\executechemicalGIVES
+ {\executechemicalarrow
+ {\chemicalsinglepicturearrow}% nodig
+ {\rightarrowfill\cr}}
+
+\def\executechemicalEQUILIBRIUM
+ {\executechemicalarrow
+ {\chemicaldoublepicturearrow}% nodig
+ {\rightarrowfill\cr\leftarrowfill\cr}}
+
+\def\executechemicalMESOMERIC
+ {\executechemicalarrow
+ {\chemicalsinglepicturearrow}% nodig
+ {$\leftarrow\hskip-1em$\rightarrowfill\cr}}
+
+\def\executechemicalsign#1[#2]%
+ {\doifelse\@@chemicallocation\v!intext
+ {\dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$%
+ \doresetsubscripts}
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ \dosetsubscripts
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$%
+ \doresetsubscripts}}}
+
+\def\executechemicalPLUS
+ {\executechemicalsign{+}}
+
+\def\executechemicalMINUS
+ {\executechemicalsign{-}}
+
+\def\executechemicalEQUAL
+ {\executechemicalsign{=}}
+
+\def\executechemicalSPACE[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ \quad}}}
+
+\def\executechemicalCHEM[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols
+ $\@@dochemicalstyle{\@@localchemicalformat#1}$}}}
+
+\def\executechemicalTEXT[#1]%
+ {\doifnot\@@chemicallocation\v!intext
+ {\setbox\chemicalsymbols\hbox
+ {\box\chemicalsymbols#1}}}
+
+%\def\executechemicalLOW[#1]%
+% {\setlowsubscripts}
+%
+%\def\executechemicalHIGH[#1]%
+% {\sethighsubscripts}
+
+\def\putchemicalrule#1#2#3#4%
+ {\ifcase\chemicaldrawingmode
+ \putrule from {#1} {#2} to {#3} {#4}
+ \or
+ \psline(#1,#2)(#3,#4)%
+ \or
+ \bgroup
+ \!!counta=#1\!!countb=#2\!!countc=#3\!!countd=#4\relax
+ \global\MPdrawingdonetrue
+ \setchemicalattributes
+ \startMPdrawing
+ x1 := \MPdivten[\the\!!counta]u ;
+ y1 := \MPdivten[\the\!!countb]u ;
+ x2 := \MPdivten[\the\!!countc]u ;
+ y2 := \MPdivten[\the\!!countd]u ;
+ draw z1--z2 ;
+ \stopMPdrawing
+ \egroup
+ \fi}
+
+\def\executechemicalcomplex#1%
+ {\bgroup
+ \putchemicalrule {0} {-\@@chemicalbottom} {0} {\@@chemicaltop}%
+ \putchemicalrule {0} {\@@chemicaltop} {#1150} {\@@chemicaltop}%
+ \putchemicalrule {0} {-\@@chemicalbottom} {#1150} {-\@@chemicalbottom}%
+ \egroup}
+
+\def\executechemicalOPENCOMPLEX[#1]%
+ {\executechemicalcomplex+\ignorespaces
+ \executechemicalSPACE[]}
+
+\def\executechemicalCLOSECOMPLEX[#1]%
+ {\executechemicalSPACE[]%
+ \executechemicalcomplex-\ignorespaces}
+
+% nog niet door midden as!
+
+\def\executechemicalverticalsymbol#1#2%
+ {\executechemicalTEXT
+ [$\left#1\relax
+ \dimen0=\@@chemicalunit
+ \scratchcounter=\@@chemicaltop
+ \advance\scratchcounter by \@@chemicalbottom
+ \dimen0=\scratchcounter\dimen0
+ \vcenter to \dimen0{}
+ \dimen2=\@@chemicalunit
+ \dimen2=\@@chemicalright\dimen0
+ \vcenter{\leftskip1em\hsize\dimen2\relax\strut#2\strut}%
+ \right.$]}%
+
+\def\executechemicalUPARROW[#1]%
+ {\executechemicalverticalsymbol\uparrow{#1}}
+
+\def\executechemicalDOWNARROW[#1]%
+ {\executechemicalverticalsymbol\downarrow{#1}}
+
+\def\executechemicalUPDOWNARROW[#1]%
+ {\executechemicalverticalsymbol\updownarrow{#1}}
+
+\let\setchemicalattributes\relax
+
+\setupchemical
+ [\c!width=0,
+ \c!height=0,
+ \c!left=0,
+ \c!right=0,
+ \c!top=0,
+ \c!bottom=0,
+ \c!bodyfont=\the\bodyfontsize,
+ \c!resolution=\outputresolution,
+ \c!scale=\v!medium,
+ \c!size=\v!medium,
+ \c!textsize=\v!big,
+ \c!frame=\v!off,
+ \c!axis=\v!off,
+ \c!state=\v!start,
+ \c!style=\rm,
+ \c!location=,
+ \c!option=,
+ \c!offset=LOW,
+ \c!alternative=1,
+ \c!color=,
+ \c!rulethickness=,
+ \c!rulecolor=,
+ \c!factor=1]
+
+% Tijdelijk plaatsen we deze extra macro's hier.
+%
+% mathontop: \mtop {} {}
+% textontop: \ttop {} {}
+
+\def\putontop#1#2%
+ {\vbox
+ {\halign
+ {\strut\hss##\hss\cr
+ #1\cr
+ #2\cr}}}
+
+\def\ttop#1#2%
+ {\putontop{\tx#1}{#2}}
+
+\def\mtop#1#2%
+ {\vbox
+ {\offinterlineskip
+ \halign
+ {\hss##\hss\cr
+ $\scriptscriptstyle#1$\cr
+ \noalign{\vskip.5ex}%
+ $#2$\cr}}}
+
+\def\ctop#1#2%
+ {\vbox
+ {\offinterlineskip
+ \halign
+ {\hss##\hss\cr
+ $\@@dochemicalstyle{\@@localchemicalformat\scriptscriptstyle#1}$\cr
+ \noalign{\vskip.5ex}%
+ $\@@dochemicalstyle{\@@localchemicalformat#2}$\cr}}}
+
+%D Here are a couple of goodies:
+%D
+%D \startitemize
+%D \item styles hooked into \CONTEXT\ style mechanism
+%D \item support for color and rulethickness (mp mode only)
+%D \item position tracking
+%D \stopitemize
+
+\let\@@chemicalrulecolor\empty
+\let\@@chemicalcolor \empty
+
+\def\setchemicalattributes
+ {\scratchdimen\@@chemicalrulethickness
+ \def\chemicalattributes
+ {withpen pencircle scaled \the\scratchdimen\space
+ withcolor }%
+ \doifelsenothing\@@chemicalrulecolor
+ {\edef\chemicalattributes{\chemicalattributes black}}
+ {\edef\chemicalattributes{\chemicalattributes \MPcolor{\@@chemicalrulecolor}}}%
+ \startMPdrawing
+ drawoptions (\chemicalattributes) ;
+ \stopMPdrawing}
+
+\unexpanded\def\@@dochemicalcolor
+ {\dousecolorparameter\@@chemicalcolor}
+
+\unexpanded\def\@@dochemicalstyle
+ {\dousestyleparameter\@@chemicalstyle}
+
+\setupchemical
+ [\c!rulethickness=\linewidth,
+ \c!rulecolor=,
+ \c!color=]
+
+\def\cpos#1#2%
+ {\iftrialtypesetting
+ #2%
+ \else
+ \bgroup
+ \globalpushmacro\dowithchemical
+ \gdef\dowithchemical##1{\hpos{#1}{##1}\globalpopmacro\dowithchemical}%
+ #2%
+ \egroup
+ \fi}
+
+\protect \endinput
+
+% \startchemical[axis=on,frame=yes]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=small,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=medium,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
+
+% \startchemical[size=big,scale=big,axis=on,frame=yes,factor=1.5]
+% \chemical[SIX,ROT2,B,R36,RZ6][CH_3]
+% \chemical[PB:RZ3,ONE,Z05,SB5,EP37,PE][O,H]
+% \stopchemical
diff --git a/tex/context/modules/mkiv/s-art-01.mkiv b/tex/context/modules/mkiv/s-art-01.mkiv
new file mode 100644
index 000000000..601ee1adc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-art-01.mkiv
@@ -0,0 +1,62 @@
+\unprotect
+
+\startmodule[art-01]
+
+\definemeasure [article:margin] [\paperheight/20] % was 15, see xtables-mkiv for results
+\definemeasure [overview:margin] [\paperheight/30]
+
+\definelayout
+ [article]
+ [\c!topspace=\measure{article:margin},
+ \c!bottomspace=\measure{article:margin},
+ \c!backspace=\measure{article:margin},
+ \c!header=\measure{article:margin},
+ \c!footer=0pt,
+ \c!width=\v!middle,
+ \c!height=\v!middle]
+
+
+\definelayout
+ [overview]
+ [\c!topspace=\measure{overview:margin},
+ \c!bottomspace=\measure{overview:margin},
+ \c!backspace=\measure{overview:margin},
+ \c!header=\measure{overview:margin},
+ \c!footer=0pt,
+ \c!width=\v!middle,
+ \c!height=\v!middle]
+
+\setuplayout
+ [article]
+
+\setupbodyfont
+ [dejavu,10pt] % 12pt is just to large and we use this for all kind of demos
+
+\setupwhitespace
+ [\v!big]
+
+\setuphead
+ [\v!chapter]
+ [\c!style=\bfc,
+ \c!headerstate=\v!high,
+ \c!interaction=\v!all]
+
+\setuphead
+ [\v!section]
+ [\c!style=\bfb]
+
+\setuphead
+ [\v!subsection]
+ [\c!style=\bfa]
+
+\setuphead
+ [\v!subsubsection]
+ [\c!style=\bf,
+ \c!after=]
+
+\setuplist
+ [\c!interaction=\v!all]
+
+\protect
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/s-def-01.mkiv b/tex/context/modules/mkiv/s-def-01.mkiv
new file mode 100644
index 000000000..49e585bd0
--- /dev/null
+++ b/tex/context/modules/mkiv/s-def-01.mkiv
@@ -0,0 +1,10 @@
+% yes or no
+
+\unprotect
+
+\startsetups defaults:frontpart:pagenumbers:roman
+ \defineconversionset[\c!frontpart:\c!pagenumber][][romannumerals]
+ \setupuserpagenumber[\c!way=\v!by\v!block]
+\stopsetups
+
+\protect
diff --git a/tex/context/modules/mkiv/s-figures-names.mkiv b/tex/context/modules/mkiv/s-figures-names.mkiv
new file mode 100644
index 000000000..a2782efc9
--- /dev/null
+++ b/tex/context/modules/mkiv/s-figures-names.mkiv
@@ -0,0 +1,99 @@
+%D \module
+%D [ file=s-figures-names.mkiv,
+%D version=2017.07.17,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Figure Names,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Normally this module will be run someplace at the end of a document in some kind of tracing
+%D mode. We could hook it into \type {\stoptext} but better leave it up to the user. Loading
+%D this module upfront will not show anything useful. The main reason for making this module
+%D was that we wanted to report weird figurenames: spaces, multiple hyphens in a row, mixed
+%D hyphens and underscores, inconsistently mixed upper and lowercase, etc.
+%D
+%D If you only want info in the logfile, you can use:
+%D
+%D \starttyping
+%D \enabletrackers[graphics.lognames]
+%D \stoptyping
+%D
+%D This directive is persistent and can be issued any time before the end of the run.
+
+\startmodule[figures-names]
+
+\startluacode
+
+local context = context
+local ctx_NC = context.NC
+local ctx_NR = context.NR
+local ctx_red = context.red
+local ctx_starttabulate = context.starttabulate
+local ctx_stoptabulate = context.stoptabulate
+local ctx_hyphenatedname = context.hyphenatedfilename
+
+trackers.enable("graphics.lognames")
+
+context.start()
+
+ context.switchtobodyfont { "tt,small" }
+
+ local template = { "|Bl|p|" }
+
+ for _, data in table.sortedhash(figures.found) do
+ ctx_starttabulate(template)
+ local badname = data.badname
+ local found = data.found
+ ctx_NC()
+ context("asked name")
+ ctx_NC()
+ if badname then
+ ctx_red()
+ end
+ context(data.askedname)
+ ctx_NC() ctx_NR()
+ if found then
+ ctx_NC()
+ context("format")
+ ctx_NC()
+ context(data.format)
+ ctx_NC() ctx_NR()
+ ctx_NC()
+ context("found file")
+ ctx_NC()
+ ctx_hyphenatedname(data.foundname)
+ -- context(data.foundname)
+ ctx_NC() ctx_NR()
+ ctx_NC()
+ context("used file")
+ ctx_NC()
+ ctx_hyphenatedname(data.fullname)
+ -- context(data.fullname)
+ ctx_NC() ctx_NR()
+ if badname then
+ ctx_NC()
+ context("comment")
+ ctx_NC()
+ context("bad name")
+ ctx_NC() ctx_NR()
+ end
+ else
+ ctx_NC()
+ context("comment")
+ ctx_NC()
+ context(data.comment or "not found")
+ ctx_NC() ctx_NR()
+ end
+ ctx_stoptabulate()
+ end
+
+context.stop()
+
+\stopluacode
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/s-fnt-10.mkiv b/tex/context/modules/mkiv/s-fnt-10.mkiv
new file mode 100644
index 000000000..731c4be39
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fnt-10.mkiv
@@ -0,0 +1,169 @@
+%D \module
+%D [ file=s-fnt-01,
+%D version=2006.10.10, % guess
+%D title=\CONTEXT\ Style File,
+%D subtitle=Listing Glyphs in Large Fonts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% sort of obsolete
+
+\startluacode
+local fontdata = fonts.hashes.identifiers
+
+-- function fonts.tracers.show_all()
+-- local tfmdata = fontdata[font.current()]
+-- if tfmdata and tfmdata.shared then
+-- local NC, NR, char = context.NC, context.NR, context.char
+-- context.starttabulate { "|l|r|c|" }
+-- for unicode, description in fonts.iterators.characters(tfmdata) do
+-- NC() context(description.name) NC() context(unicode) NC() char(unicode) NC() NR()
+-- end
+-- context.stoptabulate()
+-- end
+-- end
+
+local context = context
+local escaped = context.escaped
+
+function fonts.tracers.show_all()
+ local tfmdata = fontdata[font.current()]
+ if tfmdata then
+ local NC, NR, HL, char, bold, tttf = context.NC, context.NR, context.HL, context.char, context.bold, context.tttf
+ local descriptions = tfmdata.descriptions or { }
+ local data = characters.data
+ -- context.setuptabulate { header = "repeat" }
+ context.starttabulatehead()
+ NC() bold("unicode")
+ NC() bold("visual")
+ NC() bold("index")
+ NC() bold("glyph")
+ NC() bold("adobe")
+ NC() bold("context")
+ NC() NR()
+ context.stoptabulatehead()
+ context.starttabulate { "|l|c|l|p|p|p|" }
+ for unicode, chr in fonts.iterators.characters(tfmdata) do
+ local des, dat = descriptions[unicode], data[unicode]
+ local index = chr.index or 0
+ local cname = (dat and dat.contextname) or ""
+ local aname = (dat and dat.adobename) or ""
+ local gname = (des and des.name) or ""
+ local mname = dat and dat.mathname
+ if type(mname) ~= "string" then
+ mname = ""
+ end
+ local mspec = dat and dat.mathspec
+ if mspec then
+ for m=1,#mspec do
+ local n = mspec[m].name
+ if n then
+ if mname == "" then
+ mname = n
+ else
+ mname = mname .. " " .. n
+ end
+ end
+ end
+ end
+ if mname ~= "" then
+ mname = "m: " .. mname
+ if cname ~= "" then
+ cname = cname .. " " .. mname
+ else
+ cname = mname
+ end
+ end
+ NC() tttf() context("U+%05X",unicode)
+ NC() char(unicode)
+ NC() tttf() context("%05X",index)
+ NC() if gname ~= "" then tttf() escaped(gname) end
+ NC() if aname ~= "" then tttf() context(aname) end
+ NC() if cname ~= "" then tttf() context(cname) end
+ NC() NR()
+ end
+ context.stoptabulate()
+ else
+ context("problems")
+ end
+end
+
+function fonts.tracers.show_glyphs()
+ local tfmdata = fontdata[font.current()]
+ if tfmdata then
+ for unicode, chr in fonts.iterators.characters(tfmdata) do
+ context.showglyph(unicode)
+ end
+ end
+end
+\stopluacode
+
+\unexpanded\def\ShowCompleteFont#1#2#3%
+ {\bgroup
+ \page
+ \font\TestFont=#1 at #2
+ \setuplayout[style=\TestFont]
+ \setupheadertexts[]
+ \setupfootertexts[#1 -- \pagenumber]
+ \setupfootertexts[pagenumber]
+ \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm]
+ \TestFont
+ \nonknuthmode
+ \startcolumns[n=#3]
+ \TestFont
+ \ctxlua { fonts.tracers.show_all() }
+ \stopcolumns
+ \page
+ \egroup}
+
+\unexpanded\def\ShowAllGlyphs#1#2#3%
+ {\bgroup
+ \page
+ \def\showglyph##1{\dontleavehmode\strut\char##1\relax\par}
+ \font\TestFontA=#1 at 12pt
+ \font\TestFontB=#1 at #2
+ \setuplayout[style=\TestFontA]
+ \setupheadertexts[]
+ \setupfootertexts[#1\space\endash\space\pagenumber]
+ \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm,header=1cm,footer=2cm]
+ \TestFontB \setupinterlinespace[line=1.2\dimexpr#2\relax] \raggedcenter
+ \nonknuthmode
+ \startcolumns[n=#3]
+ \TestFontB
+ \ctxlua { fonts.tracers.show_glyphs() }
+ \stopcolumns
+ \page
+ \egroup}
+
+\continueifinputfile{s-fnt-10.mkiv}
+
+\starttext
+
+% \ShowCompleteFont{name:dejavusansmono}{10pt}{1}
+% \ShowCompleteFont{name:dejavuserif}{10pt}{2}
+% \ShowCompleteFont{name:officinasansbookitcregular}{10pt}{2}
+% \ShowCompleteFont{name:officinaserifbookitcregular}{10pt}{2}
+% \ShowCompleteFont{name:serpentineserifeflight}{10pt}{2}
+\ShowCompleteFont{name:lmroman10-regular}{10pt}{1}
+% \ShowCompleteFont{name:lmtypewriter10-regular}{10pt}{2}
+% \ShowCompleteFont{lt55485}{10pt}{2}
+% \ShowCompleteFont{lmr10}{10pt}{2}
+% \ShowCompleteFont{lbr}{10pt}{2}
+% \ShowCompleteFont{name:Cambria}{10pt}{2}
+% \ShowCompleteFont{name:CambriaMath}{10pt}{2}
+% \ShowCompleteFont{name:texgyrepagella-regular}{10pt}{2}
+% \ShowCompleteFont{name:texgyrechorus-mediumitalic}{10pt}{2}
+% \ShowAllGlyphs {name:texgyrepagella-regular} {48pt}{2}
+% \ShowAllGlyphs {name:texgyrechorus-mediumitalic}{48pt}{2}
+% \ShowCompleteFont{name:euler10-regular}{10pt}{2}
+
+% \ShowCompleteFont{name:palatinosansinformalcombold}{20pt}{2}
+% \ShowCompleteFont{name:palatinonovaregular}{11pt}{2}
+% \ShowCompleteFont{pirat.ttf}{12pt}{1}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fnt-20.mkiv b/tex/context/modules/mkiv/s-fnt-20.mkiv
new file mode 100644
index 000000000..584043099
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fnt-20.mkiv
@@ -0,0 +1,161 @@
+%D \module
+%D [ file=s-fnt-20,
+%D version=2009.01.10,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Tracing Feature Application (1),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This file is used by Idris and me in the process of getting the
+%D best arabic fonts getting rendered best. As such it might change.
+
+% \setvariables
+% [otftracker]
+% [title=Reverse Chaining,
+% figure=test-003-volt.pdf,
+% font=husayni,
+% sample={ببب بببب ببببب بببببب}]
+
+\def\checkedotftrackerfeature #1{otftracker-\ifnum\featureattribute{otftracker-#1}=\zerocount default\else#1\fi}
+\def\checkedotftrackerdirection#1{\csname otftracker-direction-\ifcsname otftracker-direction-#1\endcsname#1\else default\fi\endcsname}
+
+% we can consider adding a dir key to features
+
+\definefontfeature
+ [otftracker-default]
+ [default]
+ [mode=node]
+
+\definefontfeature
+ [otftracker-arabtype]
+ [mode=node,analyze=yes,
+ language=dflt,script=arab,ccmp=yes,
+ init=yes,medi=yes,fina=yes,isol=yes,
+ liga=yes,dlig=yes,rlig=yes,clig=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+% \definefontfeature
+% [otftracker-husayni]
+% [analyze=yes,mode=node,
+% language=dflt,script=arab,ccmp=yes,
+% init=yes,medi=yes,fina=yes,isol=yes,
+% calt=yes,
+% mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+\definefontfeature
+ [otftracker-husayni]
+ [analyze=yes,mode=node,
+ language=dflt,script=arab,
+ init=yes,medi=yes,fina=yes,
+ rlig=yes,
+ ccmp=yes,
+ ss01=yes, % full Allah, Muhammad, Allahumma
+ ss05=yes, % full Jiim stacking
+ ss09=yes, % full Haa stacking
+ ss10=yes, % partial dipped Miim
+ ss13=yes, % full stacked Miim
+ ss15=yes, % full stacked Laam-on-Miim
+ ss17=yes, % full stacked Ayn-on-Miim
+ ss19=yes, % LM_im
+ ss24=yes, % BX specials
+ ss25=yes, % LH_im specials
+ ss26=yes, % full Yaa.final specials
+ ss27=yes, % partial thin Miim.final
+ ss31=yes, % partial Raa.final contexts
+ ss34=yes, % partial Raa.final contexts
+ ss35=yes, % full Kaaf contexts
+ ss36=yes, % full Laam contexts
+ ss37=yes, % Miim-Miim contexts
+ ss38=yes, % fancy thin Haa.medial-Miim.final
+ ss39=yes, % high and low Baa strings
+ ss40=yes, % diagonal entry
+ ss41=yes, % initial alternates
+ mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+\definefontfeature
+ [otftracker-simplenaskhi]
+ [analyze=yes,mode=node,
+ language=dflt,script=arab,
+ init=yes,medi=yes,fina=yes,calt=yes,
+ rlig=yes,liga=yes,dlig=yes,
+ mark=yes,mkmk=yes,kern=yes,curs=yes]
+
+\setvalue{otftracker-direction-arabtype}{r2l}
+\setvalue{otftracker-direction-husayni}{r2l}
+\setvalue{otftracker-direction-simplenaskhi}{r2l}
+\setvalue{otftracker-direction-default}{}
+
+\setvariables
+ [otftracker]
+ [font=Serif,
+ features=\checkedotftrackerfeature{\getvariable{otftracker}{font}},
+ direction=\checkedotftrackerdirection{\getvariable{otftracker}{font}},
+ size=48pt,
+ figure=,
+ title=Feature Check,
+ sample=no sample,
+ set=\setups{otftracker}]
+
+\setuplayout
+ [topspace=1.5cm,
+ backspace=1.5cm,
+ width=middle,
+ height=middle,
+ header=1.5cm,
+ footer=1.5cm]
+
+\setuphead
+ [chapter]
+ [header=high,
+ number=no]
+
+\setupfootertexts
+ [chapter]
+
+\setupalign
+ [flushleft]
+
+\setupcolors
+ [state=start]
+
+\startsetups otftracker
+ \setupbodyfont[tt,10pt]
+ \starttext
+ \normalexpanded{\startchapter[title={\getvariable{otftracker}{title}}]}
+ \doifsomething {\getvariable{otftracker}{figure}} {
+ \startlinecorrection
+ \externalfigure[\getvariable{otftracker}{figure}][maxwidth=\hsize,frame=on]
+ \stoplinecorrection
+ }
+ \showotfcomposition
+ {\getvariable{otftracker}{font}*\getvariable{otftracker}{features} at \getvariable{otftracker}{size}}
+ {\getvariable{otftracker}{direction}}
+ {\getvariable{otftracker}{sample}}
+ \stopchapter
+ \stoptext
+\stopsetups
+
+\continueifinputfile{s-fnt-20.mkiv}
+
+\usemodule[art-01]
+
+\setupbodyfont
+% [cambria]
+ [dejavu]
+
+\starttext
+
+\setvariables
+ [otftracker]
+ [font=Serif,
+ size=48pt,
+ figure=,
+ title=Feature Check,
+ sample={affiliation}]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fnt-21.mkiv b/tex/context/modules/mkiv/s-fnt-21.mkiv
new file mode 100644
index 000000000..10d5a4623
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fnt-21.mkiv
@@ -0,0 +1,64 @@
+%D \module
+%D [ file=s-fnt-20,
+%D version=2009.01.10,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Tracing Feature Application (2),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module is related to:
+
+\usemodule[fnt-20]
+
+\setvariables
+ [otftracker]
+ [set=\setups{araball}]
+
+\startsetups araball
+ \begingroup
+ \setupcolors[state=start]%
+ \enabletrackers[otf.analyzing]% beware, kind of global
+ \ruledhbox \bgroup
+ \definedfont[\getvariable{otftracker}{font}*\getvariable{otftracker}{features} at \getvariable{otftracker}{size}]%
+ \ifnum\getvariable{otftracker}{direction}<0 \textdir TRT\else\ifnum\getvariable{otftracker}{direction}>0 \textdir TLT\fi\fi\relax
+ \getvariable{otftracker}{sample}%
+ \egroup
+ \disabletrackers[otf.analyzing]%
+ \endgroup
+\stopsetups
+
+\unexpanded\def\ShowOtfTrackerSample#1%
+ {\doiffile{#1}
+ {\blank
+ \startlinecorrection
+ \vbox \bgroup
+ \forgetall
+ \setbox\scratchbox\hbox{\component #1 \relax}
+ \hbox{\copy\scratchbox\quad\lower\dp\scratchbox\hbox{\ruledhbox{\externalfigure[#1-volt.pdf][height=\htdp\scratchbox]}}}
+ \hbox{\strut\tttf#1}%
+ \egroup
+ \stoplinecorrection
+ \blank}}
+
+\endinput
+
+% \usemodule[fnt-21]
+%
+% \starttext
+%
+% \setvariables
+% [otftracker]
+% [direction=-1,
+% sample=لا,
+% title=Test,
+% font=file:arabtype,
+% % font=file:husayni,
+% % font=file:scheherazaderegot,
+% features=arabic]
+%
+% \stoptext
diff --git a/tex/context/modules/mkiv/s-fnt-24.mkiv b/tex/context/modules/mkiv/s-fnt-24.mkiv
new file mode 100644
index 000000000..2e6b9a591
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fnt-24.mkiv
@@ -0,0 +1,83 @@
+%D \module
+%D [ file=s-fnt-24,
+%D version=2009.02.06,
+%D title=\CONTEXT\ Style File,
+%D subtitle=CJK Glyph Combination Testing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\def\ShowChineseCombiChar#1#2#3#4%
+ {\blank[small]
+ \dontleavehmode
+ \hbox\bgroup
+ \dontcomplain
+ \setstrut
+ \hbox to 7em{\ruledhbox{\char#1}\hskip.25em\type{+}\hskip.25em\ruledhbox{\char#2}\hskip.25em\type{=}\hskip.25em\ruledhbox{\char#1\char#2}\hss}\relax
+ \ruledvtop{\hsize1em\char#1\char#2}\relax
+ \hskip2em
+ \ruledvtop{\hsize.625em\char#1\char#2}\relax
+ \hskip2em
+ \ruledvtop{\hsize1.5em\char#1\char#2}\relax
+ \hskip2em
+ \type{#3 + #4}\relax
+ \egroup
+ \blank[small]}
+
+\startluacode
+local example = {
+ korean = 0x0AC00,
+ chinese = 0x04E55,
+ full_width_open = 0x03008,
+ full_width_close = 0x03009,
+ half_width_open = 0x02018,
+ half_width_close = 0x02019,
+ hyphen = 0x02026,
+ non_starter = 0x03005,
+ other = 0x0004D, -- M
+}
+
+function fonts.analyzers.cjktest(first,second)
+ for k, v in next, example do
+ if (not first or first == "") or first == k then
+ for kk, vv in next, example do
+ if (not second or second == "") or second == kk then
+ context.ShowChineseCombiChar(v,vv,k,kk)
+ end
+ end
+ end
+ end
+end
+\stopluacode
+
+\unexpanded\def\ShowCombinationsKorean
+ {\dodoubleempty\doShowCombinationsKorean}
+
+\def\doShowCombinationsKorean[#1][#2]%
+ {\startpacked
+ \setscript[hangul]
+ \setupcolors[\c!state=\v!start]
+ \enabletrackers[cjk.analyzing]
+ \ctxlua{fonts.analyzers.cjktest("#1","#2")}\par % !
+ \disabletrackers[cjk.analyzing]
+ \stoppacked}
+
+\unexpanded\def\ShowCombinationsChinese
+ {\dodoubleempty\doShowCombinationsChinese}
+
+\def\doShowCombinationsChinese[#1][#2]%
+ {\startpacked
+ \setscript[hanzi]
+ \setupcolors[\c!state=\v!start]
+ \enabletrackers[cjk.analyzing]
+ \ctxlua{fonts.analyzers.cjktest("#1","#2")}\par % !
+ \disabletrackers[cjk.analyzing]
+ \stoppacked}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-fonts-charts.mkiv b/tex/context/modules/mkiv/s-fonts-charts.mkiv
new file mode 100644
index 000000000..e94b52a2e
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-charts.mkiv
@@ -0,0 +1,204 @@
+%D \module
+%D [ file=s-fonts-charts,
+%D version=2015.08.08,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Fonts Charts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% begin info
+%
+% title : show unicode blocks
+%
+% comment : show charts of a given fgont
+%
+% end info
+
+\startmodule[fonts-charts]
+
+% \registerctxluafile{s-fonts-charts}{}
+\starttexdefinition unexpanded FontChartSetSlot #1#2
+ \dontleavehmode
+ \setbox\scratchbox\vbox to 1cm \bgroup
+ \vss
+ \hbox to 1cm \bgroup
+ \infofont \hss\raise.25mm\hbox{#2}\hss
+ \egroup
+ \egroup
+ \wd\scratchbox0mm
+ \ht\scratchbox5mm
+ \dp\scratchbox5mm
+ \box\scratchbox
+ \setbox\scratchbox\ruledhbox to 1cm \bgroup
+ \hss\char#1\hss
+ \egroup
+ \ht\scratchbox5mm
+ \dp\scratchbox5mm
+ \box\scratchbox
+\stoptexdefinition
+
+\starttexdefinition unexpanded FontChartNoSlot
+ \dontleavehmode
+ \setbox\scratchbox\hbox to 1cm \bgroup
+ % empty
+ \egroup
+ \ht\scratchbox5mm
+ \dp\scratchbox5mm
+ \box\scratchbox
+\stoptexdefinition
+
+\starttexdefinition unexpanded FontChartSetLegend #1
+ \dontleavehmode
+ \setbox\scratchbox\hbox to 1cm \bgroup
+ \infofont\hss#1\hss
+ \egroup
+ \ht\scratchbox5mm
+ \dp\scratchbox5mm
+ \box\scratchbox
+\stoptexdefinition
+
+\starttexdefinition unexpanded FontChartSetCaption #1#2
+ \dontleavehmode
+ \setbox\scratchbox\hbox to 16cm \bgroup
+ \infofontbold\hskip1cm#1: #2\hss
+ \egroup
+ \ht\scratchbox7.5mm
+ \dp\scratchbox2.5mm
+ \box\scratchbox
+\stoptexdefinition
+
+\starttexdefinition unexpanded FontChartGap
+ \kern .5mm
+\stoptexdefinition
+
+\startluacode
+ local div, mod = math.div, math.mod
+ local formatters = string.formatters
+
+ moduledata.fonts = moduledata.fonts or { }
+ moduledata.fonts.charts = moduledata.fonts.charts or { }
+
+ function moduledata.fonts.charts.show(settings)
+
+ local settings = utilities.parsers.settings_to_hash(settings)
+
+ local filename = settings.filename or ""
+ local fontid = true
+ local newpage = settings.page == interfaces.variables.yes
+
+ if filename ~= "" then
+ fontid = fonts.definers.internal({ name = filename, size = "10pt" },"chartfont")
+ end
+
+ local ranges = { }
+ local data = fonts.hashes.identifiers[fontid]
+ local private = fonts.constructors.privateoffset
+ local chars = data.characters
+
+ for u in table.sortedhash(chars) do
+ if u >= private then
+ break
+ else
+ ranges[div(u,0xFF)] = true
+ end
+ end
+
+ local ctx_setlegend = context.FontChartSetLegend
+ local ctx_noslot = context.FontChartNoSlot
+ local ctx_setslot = context.FontChartSetSlot
+ local ctx_setcaption = context.FontChartSetCaption
+ local ctx_par = context.par
+ local ctx_gap = context.FontChartGap
+
+ for r in table.sortedhash(ranges) do
+ if newpage then
+ context.page()
+ end
+ context.startframed { offset = "overlay", frame = "off", align = "normal" }
+ if filename ~= "" then
+ context.chartfont()
+ end
+ context.dontcomplain()
+ context.offinterlineskip()
+ ctx_noslot()
+ for i=0,0xF do
+ ctx_setlegend(formatters["%03X"](r*0x10+i))
+ end
+ r = r * 0xFF
+ ctx_par()
+ for i=0,0xF do
+ ctx_setlegend(formatters["%0X"](i))
+ ctx_gap()
+ for j=0,0xF do
+ local u = r + i*0x10 + j
+ local d = chars[u]
+ if d then
+ ctx_setslot(u,formatters["%04X"](u))
+ else
+ ctx_noslot()
+ end
+ if j ~= 0xF then
+ ctx_gap()
+ end
+ end
+ ctx_par()
+ ctx_gap()
+ end
+ ctx_setcaption(formatters["%04X-%04X"](r,r+0xFF),file.basename(data.properties.filename))
+ ctx_par()
+ context.stopframed()
+ if newpage then
+ context.page()
+ end
+ end
+ end
+\stopluacode
+
+\installmodulecommandluasingle \showfontchart {moduledata.fonts.charts.show}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-charts.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showfontchart[filename=LucidaBrightOT.otf,page=yes]
+ \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes]
+ \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes]
+ \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes]
+
+ \showfontchart[filename=LucidaSansOT.otf,page=yes]
+ \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes]
+ \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes]
+ \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes]
+
+ \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes]
+ \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes]
+ \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes]
+ \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes]
+
+ \showfontchart[filename=LucidaConsoleDK.otf,page=yes]
+ \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes]
+ \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes]
+ \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes]
+
+ \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes]
+ \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes]
+ \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes]
+ \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes]
+
+ \showfontchart[filename=LucidaBrightMathOT.otf,page=yes]
+ \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes]
+
+ \showfontchart[filename=LucidaBlackletterOT.otf,page=yes]
+ \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes]
+ \showfontchart[filename=LucidaHandwritingOT.otf,page=yes]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-coverage.lua b/tex/context/modules/mkiv/s-fonts-coverage.lua
new file mode 100644
index 000000000..dd772d5f0
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-coverage.lua
@@ -0,0 +1,123 @@
+if not modules then modules = { } end modules ['s-fonts-coverage'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-coverage.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.coverage = moduledata.fonts.coverage or { }
+
+local upper, format = string.upper, string.format
+local lpegmatch = lpeg.match
+local concat = table.concat
+
+local context = context
+local NC, NR, HL = context.NC, context.NR, context.HL
+local char, bold, getvalue = context.char, context.bold, context.getvalue
+
+local chardata = characters.data
+
+function moduledata.fonts.coverage.showcomparison(specification)
+
+ specification = interfaces.checkedspecification(specification)
+
+ local fontfiles = utilities.parsers.settings_to_array(specification.list or "")
+ local pattern = upper(specification.pattern or "")
+
+ local present = { }
+ local names = { }
+ local files = { }
+ local chars = { }
+
+ if not pattern then
+ -- skip
+ elseif pattern == "" then
+ pattern = nil
+ elseif tonumber(pattern) then
+ pattern = tonumber(pattern)
+ else
+ pattern = lpeg.oneof(utilities.parsers.settings_to_array(pattern))
+ pattern = (1-pattern)^0 * pattern
+ end
+
+ for i=1,#fontfiles do
+ local fontname = format("testfont-%s",i)
+ local fontfile = fontfiles[i]
+ local fontsize = tex.dimen.bodyfontsize
+ local id, fontdata = fonts.definers.define {
+ name = fontfile,
+ size = fontsize,
+ cs = fontname,
+ }
+ if id and fontdata then
+ for k, v in next, fontdata.characters do
+ present[k] = true
+ end
+ names[#names+1] = fontname
+ files[#files+1] = fontfile
+ chars[#names] = fontdata.characters
+ end
+ end
+
+ local t = { }
+
+ context.starttabulate { "|Tr" .. string.rep("|l",#names) .. "|" }
+ for i=1,#files do
+ local file = files[i]
+ t[#t+1] = i .. "=" .. file
+ NC()
+ context(i)
+ NC()
+ context(file)
+ NC()
+ NR()
+ end
+ context.stoptabulate()
+
+ context.setupfootertexts {
+ table.concat(t," ")
+ }
+
+ context.starttabulate { "|Tl" .. string.rep("|c",#names) .. "|Tl|" }
+ NC()
+ bold("unicode")
+ NC()
+ for i=1,#names do
+ bold(i)
+ NC()
+ end
+ bold("description")
+ NC()
+ NR()
+ HL()
+ for k, v in table.sortedpairs(present) do
+ if k <= 0 then
+ -- ignore
+ elseif k >= 0x110000 then
+ logs.report("warning","weird character %U",k)
+ else
+ local description = chardata[k].description
+ if not pattern or (pattern == k) or (description and lpegmatch(pattern,description)) then
+ NC()
+ context("%05X",k)
+ NC()
+ for i=1,#names do
+ getvalue(names[i])
+ if chars[i][k] then
+ char(k)
+ else
+ -- missing
+ end
+ NC()
+ end
+ context(description)
+ NC()
+ NR()
+ end
+ end
+ end
+ context.stoptabulate()
+
+end
diff --git a/tex/context/modules/mkiv/s-fonts-coverage.mkiv b/tex/context/modules/mkiv/s-fonts-coverage.mkiv
new file mode 100644
index 000000000..c09d943bc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-coverage.mkiv
@@ -0,0 +1,131 @@
+%D \module
+%D [ file=s-fonts-coverage, % s-fnt-31
+%D version=2011.01.02,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Fonts Coverage,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% begin info
+%
+% title : compare glyphs in fonts
+%
+% comment : show glyphs in several fonts alongside in order to to compare coverage
+% status : experimental, used for luatex testing
+%
+% end info
+
+\startmodule[fonts-coverage]
+
+\registerctxluafile{s-fonts-coverage}{}
+
+\installmodulecommandluasingle \showfontcomparison {moduledata.fonts.coverage.showcomparison}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-coverage.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showfontcomparison
+ [list={texgyrepagella-regular.otf,texgyretermes-regular.otf,texgyrebonum-regular.otf},
+ pattern=ogonek]
+
+ \page
+
+ % $e=mc²$ ${}²$ $²$ $x²ᶞ$ $x⁽²⁺²⁼²⁺²⁾$ $x²⁺²⁼²⁺²$ $x₅²$ $x²₅²$
+
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = {
+ % "texgyrepagella-math.otf",
+ % "texgyretermes-math.otf",
+ % "texgyrebonum-math.otf",
+ % }
+ % }
+ % \stopluacode
+
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = "pirat.ttf",
+ % }
+ % \stopluacode
+
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = {
+ % "lucidabrightot.otf",
+ % "cambria.ttf",
+ % "iwona-regular.otf",
+ % "texgyrepagella-regular.otf",
+ % "texgyretermes-regular.otf",
+ % "texgyrebonum-regular.otf",
+ % "antpolt-regular.otf",
+ % },
+ % pattern = "OGONEK"
+ % }
+ % \stopluacode
+
+ % \loadfontgoodies[lucida-math]
+ % \loadfontgoodies[lm-math]
+ %
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = {
+ % "LucidaBrightRegular.ttf",
+ % "LucidaBrightOne@lucida-math",
+ % "cambria.ttc(Cambria Math)",
+ % "xits-math.otf",
+ % "LMMath10-Regular@lmroman10-math",
+ % },
+ % }
+ % \stopluacode
+
+ % \loadfontgoodies[px-math]
+ % \loadfontgoodies[lm-math]
+ %
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = {
+ % "cambria.ttc(Cambria Math)",
+ % "xits-math.otf",
+ % -- "stixmath-regular.otf",
+ % "latinmodern-math.otf",
+ % -- "lucidabrightmathot.otf",
+ % -- "lucidabrightmathot-demi.otf",
+ % "texgyrepagella-math.otf",
+ % "texgyretermes-math.otf",
+ % "texgyrebonum-math.otf",
+ % -- "LMMath10-Regular@lmroman10-math",
+ % -- "pxmath@px-math",
+ % -- "txmath@tx-math",
+ % },
+ % }
+ % \stopluacode
+
+ % \startluacode
+ % moduledata.fonts.coverage.showcomparison {
+ % list = {
+ % "dejavuserif.ttf",
+ % "dejavusans.ttf",
+ % "dejavusansmono.ttf",
+ % "lucidabrightot.otf",
+ % "cambria.ttf",
+ % "iwona-regular.otf",
+ % "texgyrepagella-regular.otf",
+ % "texgyretermes-regular.otf",
+ % "texgyrebonum-regular.otf",
+ % "antpolt-regular.otf",
+ % },
+ % pattern = "CELSIUS,FAHRENHEIT"
+ % }
+ % \stopluacode
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-features.lua b/tex/context/modules/mkiv/s-fonts-features.lua
new file mode 100644
index 000000000..0a7cf8b13
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-features.lua
@@ -0,0 +1,161 @@
+if not modules then modules = { } end modules ['s-fonts-features'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-features.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.features = moduledata.fonts.features or { }
+
+-- for the moment only otf
+
+local sortedhash = table.sortedhash
+
+local NC, NR, bold = context.NC, context.NR, context.bold
+
+function moduledata.fonts.features.showused(specification)
+
+ specification = interfaces.checkedspecification(specification)
+
+ -- local list = utilities.parsers.settings_to_set(specification.list or "all")
+
+ context.starttabulate { "|T|T|T|T|T|" }
+
+ context.HL()
+
+ NC() bold("feature")
+ NC()
+ NC() bold("description")
+ NC() bold("value")
+ NC() bold("internal")
+ NC() NR()
+
+ context.HL()
+
+ local usedfeatures = fonts.handlers.otf.statistics.usedfeatures
+ local features = fonts.handlers.otf.tables.features
+ local descriptions = fonts.handlers.otf.features.descriptions
+
+ for feature, keys in sortedhash(usedfeatures) do
+ -- if list.all or (list.otf and rawget(features,feature)) or (list.extra and rawget(descriptions,feature)) then
+ local done = false
+ for k, v in sortedhash(keys) do
+ if done then
+ NC()
+ NC()
+ NC()
+ elseif rawget(descriptions,feature) then
+ NC() context(feature)
+ NC() context("+") -- extra
+ NC() context(descriptions[feature])
+ done = true
+ elseif rawget(features,feature) then
+ NC() context(feature)
+ NC() -- otf
+ NC() context(features[feature])
+ done = true
+ else
+ NC() context(feature)
+ NC() context("-") -- unknown
+ NC()
+ done = true
+ end
+ NC() context(k)
+ NC() context(tostring(v))
+ NC() NR()
+ end
+ -- end
+ end
+
+ context.HL()
+
+ context.stoptabulate()
+
+end
+
+local function collectkerns(tfmdata,feature)
+ local combinations = { }
+ local resources = tfmdata.resources
+ local characters = tfmdata.characters
+ local sequences = resources.sequences
+ local lookuphash = resources.lookuphash
+ local feature = feature or "kern"
+ if sequences then
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ if sequence.features and sequence.features[feature] then
+ local lookuplist = sequence.subtables
+ if lookuplist then
+ for l=1,#lookuplist do
+ local lookupname = lookuplist[l]
+ local lookupdata = lookuphash[lookupname]
+ for unicode, data in next, lookupdata do
+ local kerns = combinations[unicode]
+ if not kerns then
+ kerns = { }
+ combinations[unicode] = kerns
+ end
+ for otherunicode, kern in next, data do
+ if not kerns[otherunicode] and kern ~= 0 then
+ kerns[otherunicode] = kern
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ return combinations
+end
+
+local showkernpair = context.showkernpair
+
+function moduledata.fonts.features.showbasekerns(specification)
+ -- assumes that the font is loaded in base mode
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:features:font>")
+ local tfmdata = fonts.hashes.identifiers[id]
+ local done = false
+ for unicode, character in sortedhash(tfmdata.characters) do
+ local kerns = character.kerns
+ if kerns then
+ context.par()
+ for othercode, kern in sortedhash(kerns) do
+ showkernpair(unicode,kern,othercode)
+ end
+ context.par()
+ done = true
+ end
+ end
+ if not done then
+ context("no kern pairs found")
+ context.par()
+ end
+end
+
+function moduledata.fonts.features.showallkerns(specification)
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:features:font>")
+ local tfmdata = fonts.hashes.identifiers[id]
+ local allkerns = collectkerns(tfmdata)
+ local characters = tfmdata.characters
+ if next(allkerns) then
+ for first, pairs in sortedhash(allkerns) do
+ context.par()
+ for second, kern in sortedhash(pairs) do
+ -- local kerns = characters[first].kerns
+ -- if not kerns and pairs[second] then
+ -- -- weird
+ -- end
+ showkernpair(first,kern,second,0)
+ end
+ context.par()
+ end
+ else
+ context("no kern pairs found")
+ context.par()
+ end
+end
diff --git a/tex/context/modules/mkiv/s-fonts-features.mkiv b/tex/context/modules/mkiv/s-fonts-features.mkiv
new file mode 100644
index 000000000..b81b53a71
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-features.mkiv
@@ -0,0 +1,82 @@
+%D \module
+%D [ file=s-fonts-features, % was s-fnt-41, s-fnt-27
+%D version=2012.11.27, % 2010.02.22
+%D title=\CONTEXT\ Style File,
+%D subtitle=Features,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[fonts-features]
+
+\registerctxluafile{s-fonts-features}{}
+
+\installmodulecommandluasingle \showusedfeatures {moduledata.fonts.features.showused}
+\installmodulecommandluasingle \showallkerns {moduledata.fonts.features.showallkerns}
+\installmodulecommandluasingle \showbasekerns {moduledata.fonts.features.showbasekerns}
+
+\def\kernpairheight{\strutheight}
+\def\kernpairdepth {\strutdepth}
+\def\kernpairwidth {\onepoint}
+
+\unexpanded\def\showkernpair#1#2#3% first second kern
+ {\dontleavehmode
+ \hbox \bgroup
+ \scratchdimen#2\scaledpoint
+ \kern\fontcharwd\font#1\relax
+ \ifdim\scratchdimen>\zeropoint
+ \bgroup
+ \darkgreen
+ \vrule width \scratchdimen height \kernpairheight depth \kernpairdepth
+ \egroup
+ \kern-\scratchdimen
+ \else\ifdim\scratchdimen<\zeropoint
+ \kern\scratchdimen
+ \bgroup
+ \darkred
+ \vrule width -\scratchdimen height \kernpairheight depth \kernpairdepth
+ \egroup
+ \else
+ \kern-.5\dimexpr\kernpairwidth\relax
+ \bgroup
+ \darkblue
+ \vrule width \kernpairwidth height \kernpairheight depth \kernpairdepth
+ \egroup
+ \kern-.5\dimexpr\kernpairwidth\relax
+ \fi\fi
+ \kern-\fontcharwd\font#1\relax
+ \char#1\relax
+ \char#3\relax
+ \egroup
+ \space}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-features.mkiv}
+
+\usemodule
+ [art-01]
+
+\starttext
+
+ \showusedfeatures \page
+
+ \definefontfeature[default-base][default][mode=base]
+
+ \start
+ \definedfont[Serif*default-base]
+ \showbasekerns
+ \page
+ \stop
+
+ \start
+ \bf
+ \showallkerns
+ \page
+ \stop
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-goodies.lua b/tex/context/modules/mkiv/s-fonts-goodies.lua
new file mode 100644
index 000000000..381fc45ea
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-goodies.lua
@@ -0,0 +1,117 @@
+if not modules then modules = { } end modules['s-fonts-goodies'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-goodies.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.goodies = moduledata.fonts.goodies or { }
+
+local NC, NR, HL = context.NC, context.NR, context.HL
+
+local function initialized(specification)
+ specification = interfaces.checkedspecification(specification)
+ local name = specification.name
+ if name then
+ local goodies = fonts.goodies.load(name)
+ if goodies then
+ return specification, goodies
+ end
+ end
+end
+
+function moduledata.fonts.goodies.showstylistics(specification)
+ local specification, goodies = initialized(specification)
+ if goodies then
+ local stylistics = goodies.stylistics
+ if stylistics then
+ context.starttabulate { "|Tl|Tpl|" }
+ HL()
+ NC() context.bold("feature")
+ NC() context.bold("meaning")
+ NC() NR()
+ HL()
+ for feature, meaning in table.sortedpairs(stylistics) do
+ NC() context(feature)
+ NC() context(string.lower(meaning))
+ NC() NR()
+ end
+ HL()
+ context.stoptabulate()
+ end
+ end
+end
+
+function moduledata.fonts.goodies.showfeaturesets(specification)
+ local specification, goodies = initialized(specification)
+ if goodies then
+ local featuresets = goodies.featuresets
+ if featuresets then
+ context.starttabulate { "|Tl|Tpl|" }
+ HL()
+ NC() context.bold("featureset")
+ NC() context.bold("definitions")
+ NC() NR()
+ HL()
+ for featureset, definitions in table.sortedpairs(featuresets) do
+ NC() context.type(featureset) NC()
+ for k, v in table.sortedpairs(definitions) do
+ context("%s=%S",k,v)
+ context.quad()
+ end
+ NC() NR()
+ end
+ HL()
+ context.stoptabulate()
+ end
+ end
+end
+
+function moduledata.fonts.goodies.showcolorschemes(specification)
+ local specification, goodies = initialized(specification)
+ if goodies then
+ local colorschemes = goodies.colorschemes
+ if colorschemes then
+ context.starttabulate { "|Tl|Tpl|" }
+ HL()
+ NC() context.bold("colorscheme")
+ NC() context.bold("numbers")
+ NC() NR()
+ HL()
+ for colorscheme, numbers in table.sortedpairs(colorschemes) do
+ NC() context.type(colorscheme) NC()
+ for i=1,#numbers do
+ context(i)
+ context.quad()
+ end
+ NC() NR()
+ end
+ HL()
+ context.stoptabulate()
+ end
+ end
+end
+
+function moduledata.fonts.goodies.showfiles(specification)
+ local specification, goodies = initialized(specification)
+ if goodies then
+ local files = goodies.files
+ if files and files.list then
+ for filename, specification in table.sortedpairs(files.list) do
+ context.start()
+ context.dontleavehmode()
+ context.definedfont{ filename .. "*default" }
+ context("%s-%s-%s-%s-%s",
+ specification.name or files.name,
+ specification.weight or "normal",
+ specification.style or "normal",
+ specification.width or "normal",
+ specification.variant or "normal")
+ context.par()
+ context.stop()
+ end
+ end
+ end
+end
diff --git a/tex/context/modules/mkiv/s-fonts-goodies.mkiv b/tex/context/modules/mkiv/s-fonts-goodies.mkiv
new file mode 100644
index 000000000..e596507af
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-goodies.mkiv
@@ -0,0 +1,37 @@
+%D \module
+%D [ file=s-fonts-goodies, % s-fnt-26, s-fnt-28
+%D version=2009.10.26,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Goodies Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D More tables will follow here as we have many more goodies by now.
+
+\startmodule[fonts-goodies]
+
+\registerctxluafile{s-fonts-goodies}{}
+
+\installmodulecommandluasingle \showfontgoodiesstylistics {moduledata.fonts.goodies.showstylistics}
+\installmodulecommandluasingle \showfontgoodiesfeaturesets {moduledata.fonts.goodies.showfeaturesets}
+\installmodulecommandluasingle \showfontgoodiescolorschemes {moduledata.fonts.goodies.showcolorschemes}
+\installmodulecommandluasingle \showfontgoodiesfiles {moduledata.fonts.goodies.showfiles}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-goodies.mkiv}
+
+\starttext
+
+ \showfontgoodiesstylistics [name=husayni] \page
+ \showfontgoodiesfeaturesets [name=husayni] \page
+ \showfontgoodiescolorschemes[name=husayni] \page
+
+ \showfontgoodiesfiles [name=antykwapoltawskiego] \page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-ligatures.mkiv b/tex/context/modules/mkiv/s-fonts-ligatures.mkiv
new file mode 100644
index 000000000..fc49ec5c5
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-ligatures.mkiv
@@ -0,0 +1,209 @@
+%D \module
+%D [ file=s-fonts-ligatures,
+%D version=2014.12.14,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Fonts Ligatures,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% begin info
+%
+% title : show some ligature building in fonts
+%
+% comment : we trace some ligatures that have rather different implementations in fontss
+% status : experimental, used for luatex testing
+%
+% end info
+
+\definefontfeature
+ [otfligaturetest]
+ [analyze=off,
+ ccmp=yes, % brill uses that .. not really ligatures !
+ %clig=yes,
+ script=latn,
+ language=dflt]
+
+\hyphenation{xf-fi-a}
+\hyphenation{xff-i-b}
+\hyphenation{xffi-c}
+\hyphenation{xffid}
+
+\registerhyphenationexception[xf-fi-a]
+\registerhyphenationexception[xff-i-b]
+\registerhyphenationexception[xffi-c]
+\registerhyphenationexception[xffid]
+
+\starttexdefinition showotfligaturescaption #1
+ \bTD [align={flushleft,lohi},nx=3]
+ \nohyphens
+ \ttbf
+ #1
+ \eTD
+\stoptexdefinition
+
+\starttexdefinition showotfligatureslegend #1
+ \bTD [width=6em,align={flushleft,lohi}]
+ \nohyphens \ttxx original
+ \eTD
+ \bTD [width=6em,align={flushleft,lohi}]
+ \nohyphens \ttxx expanded
+ \eTD
+ \bTD [width=6em,align={flushleft,lohi}]
+ \nohyphens \ttxx traditional
+ \eTD
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesline #1#2
+ \bTD[toffset=.5ex,frame=off]
+ \starthyphenation[#1]
+ \LigatureFont
+ \showfontkerns
+ \showdiscretionaries
+ \begstrut#2\endstrut
+ \par
+ \stophyphenation
+ \eTD
+\stoptexdefinition
+
+\def\showotfligaturescells{3}
+%def\showotfligaturesnx {12}
+%def\showotfligatureswidth{18em}
+\def\showotfligaturesnx {\the\numexpr 4*\showotfligaturescells}
+\def\showotfligatureswidth{\the\dimexpr6em*\showotfligaturescells}
+
+\starttexdefinition showotfligaturesbanner #1
+ \bTR[frame=off]
+ \bTD [nx=\showotfligaturesnx,xwidth=\showotfligatureswidth,align={middle,lohi},height=4ex]
+ \tttf #1
+ \eTD
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligaturescaptions #1
+ \bTR[height=3ex,align={middle,lohi},bottomframe=off]
+ \processcommalist[#1]\showotfligaturescaption
+ \eTR
+ \bTR[height=3ex,align={middle,lohi},topframe=off]
+ \processcommalist[#1]\showotfligatureslegend
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligatureslineset #1
+ \showotfligaturesline{original} {#1}
+ \showotfligaturesline{expanded} {#1}
+ \showotfligaturesline{traditional}{#1}
+\stoptexdefinition
+
+
+\starttexdefinition showotfligaturesparagraphset #1
+ \showotfligatureslineset {
+ \hsize \zeropoint
+ \lefthyphenmin \plustwo
+ \righthyphenmin\plustwo
+ #1
+ }
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesextremeset #1
+ \showotfligatureslineset {
+ \hsize \zeropoint
+ \lefthyphenmin \plusone
+ \righthyphenmin\plusone
+ #1
+ }
+\stoptexdefinition
+
+\starttexdefinition showotfligatureslines #1
+ \bTR[height=4ex,bottomframe=off]
+ \processcommalist[#1]\showotfligatureslineset
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesparagraphs #1
+ \bTR[topframe=off]
+ \processcommalist[#1]\showotfligaturesparagraphset
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesextremes #1
+ \bTR[topframe=off]
+ \processcommalist[#1]\showotfligaturesextremeset
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesdefaults
+ \bTR
+ \bTD [nx=\showotfligaturesnx,xwidth=\showotfligatureswidth,align=middle,height=4ex,frame=off]
+ \start \LigatureFont fb \stop \quad
+ \start \LigatureFont ff \stop \quad
+ \start \LigatureFont fi \stop \quad
+ \start \LigatureFont fk \stop \quad
+ \start \LigatureFont fl \stop \quad
+ \start \LigatureFont ft \stop \quad
+ \start \LigatureFont ffb \stop \quad
+ \start \LigatureFont fff \stop \quad
+ \start \LigatureFont ffi \stop \quad
+ \start \LigatureFont ffl \stop \quad
+ \start \LigatureFont ffk \stop \quad
+ \start \LigatureFont fft \stop
+ \eTD
+ \eTR
+\stoptexdefinition
+
+\starttexdefinition showotfligaturesexample #1#2
+ \ctxlua{document.currentdiscexpansion = fonts.getdiscexpansion()}%
+ \showotfligaturescaptions {#1}
+ \showotfligatureslines {#2}
+ \showotfligaturesparagraphs{#2}
+ \showotfligaturesextremes {#2}
+ \ctxlua{fonts.setdiscexpansion(document.currentdiscexpansion)}%
+\stoptexdefinition
+
+% todo: n -> and split in lua
+
+\starttexdefinition showotfligaturesexamples
+ \showotfligaturesexample
+ {leafing,baffling,efficient,shifffahrt}
+ {leafing,baffling,efficient,shifffahrt}
+ \showotfligaturesexample
+ {offbeat,effect,ef-fective,ef\-fective}
+ {offbeat,effect,ef-fective,ef\-fective}
+ \showotfligaturesexample
+ {xf+fi+a,xff+i+b,xffi+c,xffid}
+ {xffia, xffib, xffic, xffid}
+\stoptexdefinition
+
+\starttexdefinition showotfligatures [#1]
+ \begingroup
+ \getdummyparameters[font=Regular,features=default,#1]
+ \definefont[LigatureFont][\dummyparameter{font}*\dummyparameter{features},otfligaturetest ht 2ex]
+ \bTABLE[leftframe=off,rightframe=off]
+ \showotfligaturesbanner{\dummyparameter{font} * \dummyparameter{features}}
+ \showotfligaturesdefaults
+ \showotfligaturesexamples
+ \eTABLE
+ \endgroup
+\stoptexdefinition
+
+\continueifinputfile{s-fonts-ligatures.mkiv}
+
+\starttext
+
+ \definefontfeature[fonttest][default] [mode=node,language=dflt,script=latn,ccmp=yes,liga=yes,kern=yes,mark=yes,mkmk=yes]
+ \definefontfeature[capstest][smallcaps][mode=node,language=dflt,script=latn,ccmp=yes,liga=yes,kern=yes,mark=yes,mkmk=yes]
+
+ \startTEXpage[offset=10pt] \showotfligatures[font=lmroman10-regular.otf, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=dejavu-serif.ttf, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=minionpro.otf, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=minionpro.otf, features=capstest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=brill.otf, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=gentiumplus-r.ttf, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=cambria, features=fonttest] \stopTEXpage
+ \startTEXpage[offset=10pt] \showotfligatures[font=ebgaramond12-regular.otf,features=fonttest] \stopTEXpage
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-missing.lua b/tex/context/modules/mkiv/s-fonts-missing.lua
new file mode 100644
index 000000000..9a75676a9
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-missing.lua
@@ -0,0 +1,91 @@
+if not modules then modules = { } end modules ['s-fonts-missing'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-missing.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.missing = moduledata.fonts.missing or { }
+
+local function legend(id)
+ local c = fonts.hashes.identifiers[id]
+ local privates = c.properties.privates
+ if privates then
+ local categories = table.swapped(fonts.loggers.category_to_placeholder)
+ context.starttabulate { "|c|l|" }
+ context.HL()
+ context.NC()
+ context.bold("symbol")
+ context.NC()
+ context.bold("name")
+ context.NC()
+ context.NR()
+ context.HL()
+ for k, v in table.sortedhash(privates) do
+ local tag = characters.categorytags[categories[k]]
+ if tag and tag ~= "" then
+ context.NC()
+ context.dontleavehmode()
+ context.char(v)
+ context.NC()
+ context(k)
+ context.NC()
+ context.NR()
+ end
+ end
+ context.HL()
+ context.stoptabulate()
+ end
+end
+
+function moduledata.fonts.missing.showlegend(specification)
+ specification = interfaces.checkedspecification(specification)
+ context.begingroup()
+ context.definedfont { "Mono*missing" } -- otherwise no privates added
+ context(function() legend(specification.id or font.current()) end)
+ context.endgroup()
+end
+
+local function missings()
+ local collected = fonts.checkers.getmissing()
+ for filename, list in table.sortedhash(collected) do
+ if #list > 0 then
+ context.starttabulate { "|l|l|" }
+ context.NC()
+ context.bold("filename")
+ context.NC()
+ context(file.basename(filename))
+ context.NC()
+ context.NR()
+ context.NC()
+ context.bold("missing")
+ context.NC()
+ context(#list)
+ context.NC()
+ context.NR()
+ context.stoptabulate()
+ context.starttabulate { "|l|c|l|" }
+ for i=1,#list do
+ local u = list[i]
+ context.NC()
+ context("%U",u)
+ context.NC()
+ context.char(u)
+ context.NC()
+ context(characters.data[u].description)
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+ end
+ end
+end
+
+function moduledata.fonts.missing.showcharacters(specification)
+ context.begingroup()
+ context.definedfont { "Mono*missing" } -- otherwise no privates added
+ context(function() missings() end)
+ context.endgroup()
+end
diff --git a/tex/context/modules/mkiv/s-fonts-missing.mkiv b/tex/context/modules/mkiv/s-fonts-missing.mkiv
new file mode 100644
index 000000000..c566f4995
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-missing.mkiv
@@ -0,0 +1,56 @@
+%D \module
+%D [ file=s-fonts-missing,
+%D version=2011.10.30,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Some Missing Character Info,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[fonts-missing]
+
+\registerctxluafile{s-fonts-missing}{}
+
+\installmodulecommandluasingle \showmissingcharacterslegend {moduledata.fonts.missing.showlegend}
+\installmodulecommandluasingle \showmissingcharacters {moduledata.fonts.missing.showcharacters}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-missing.mkiv}
+
+% the sooner, the more efficient, see log for details
+
+\enabletrackers[fonts.missing=replace]
+
+% \definefontfeature[default][default][missing=yes] % automatically when enabled
+
+\starttext
+
+ \page legend: \blank
+
+ \showmissingcharacterslegend
+
+ \page sample: \blank
+
+ ½ ⅓ ¼ ⅕ ⅙ ⅛ {\bf ½ ⅓ ¼ ⅕ ⅙ ⅛} \blank
+
+ \startluacode
+ for i=1,1000 do
+ local c = characters.data[i]
+ if c then
+ context.char(c.unicodeslot)
+ context.space()
+ end
+ end
+ \stopluacode
+
+ \page characters: \blank
+
+ \showmissingcharacters
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/s-fonts-shapes.lua b/tex/context/modules/mkiv/s-fonts-shapes.lua
new file mode 100644
index 000000000..8f872e4bc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-shapes.lua
@@ -0,0 +1,326 @@
+if not modules then modules = { } end modules['s-fonts-shapes'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-shapes.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.shapes = moduledata.fonts.shapes or { }
+
+local fontdata = fonts.hashes.identifiers
+
+local context = context
+local NC, NR = context.NC, context.NR
+local space, dontleavehmode, glyph, getvalue = context.space, context.dontleavehmode, context.glyph, context.getvalue
+local formatters = string.formatters
+
+function char(id,k)
+ dontleavehmode()
+ glyph(id,k)
+end
+
+local function special(id,specials)
+ if specials and #specials > 1 then
+ context("%s:",specials[1])
+ if #specials > 5 then
+ space() char(id,specials[2])
+ space() char(id,specials[3])
+ space() context("...")
+ space() char(id,specials[#specials-1])
+ space() char(id,specials[#specials])
+ else
+ for i=2,#specials do
+ space() char(id,specials[i])
+ end
+ end
+ end
+end
+
+function moduledata.fonts.shapes.showlist(specification) -- todo: ranges
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
+ local chrs = fontdata[id].characters
+ context.begingroup()
+ context.tt()
+ context.starttabulate { "|l|c|c|c|c|l|l|" }
+ context.FL()
+ NC() context.bold("unicode")
+ NC() context.bold("glyph")
+ NC() context.bold("shape")
+ NC() context.bold("lower")
+ NC() context.bold("upper")
+ NC() context.bold("specials")
+ NC() context.bold("description")
+ NC() NR()
+ context.TL()
+ for k, v in next, characters.data do
+ if chrs[k] then
+ NC() context("0x%05X",k)
+ NC() char(id,k) -- getvalue(cs) context.char(k)
+ NC() char(id,v.shcode)
+ NC() char(id,v.lccode or k)
+ NC() char(id,v.uccode or k)
+ NC() special(id,v.specials)
+ NC() context.tx(v.description)
+ NC() NR()
+ end
+ end
+ context.stoptabulate()
+ context.endgroup()
+end
+
+function moduledata.fonts.shapes.showlist(specification) -- todo: ranges
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
+ local chrs = fontdata[id].characters
+ context.begingroup()
+ context.tt()
+ context.starttabulate { "|l|c|c|c|c|l|l|" }
+ context.FL()
+ NC() context.bold("unicode")
+ NC() context.bold("glyph")
+ NC() context.bold("shape")
+ NC() context.bold("lower")
+ NC() context.bold("upper")
+ NC() context.bold("specials")
+ NC() context.bold("description")
+ NC() NR()
+ context.TL()
+ for k, v in next, characters.data do
+ if chrs[k] then
+ NC() context("0x%05X",k)
+ NC() char(id,k)
+ NC() char(id,v.shcode)
+ NC() char(id,v.lccode or k)
+ NC() char(id,v.uccode or k)
+ NC() special(id,v.specials)
+ NC() context.tx(v.description)
+ NC() NR()
+ end
+ end
+ context.stoptabulate()
+ context.endgroup()
+end
+
+local descriptions = nil
+local characters = nil
+
+local function showglyphshape(specification)
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
+ local tfmdata = fontdata[id]
+ local charnum = tonumber(specification.character)
+ if not charnum then
+ charnum = fonts.helpers.nametoslot(n)
+ end
+ context.start()
+ context.dontleavehmode()
+ context.obeyMPboxdepth()
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local parameters = tfmdata.parameters
+ local c = characters[charnum]
+ local d = descriptions[charnum]
+ if d then
+ local factor = (parameters.size/parameters.units)*((7200/7227)/65536)
+ local llx, lly, urx, ury = unpack(d.boundingbox)
+ llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor
+ local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor
+ local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor
+ local anchors, math = d.anchors, d.math
+ context.startMPcode()
+ context("numeric lw ; lw := .125bp ;")
+ context("pickup pencircle scaled lw ;")
+ context('picture p ; p := image(draw textext.drt("\\getuvalue{%s}\\gray\\char%s");); draw p ;',cs,charnum)
+ context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury)
+ context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0)
+ context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
+ context("defaultscale := 0.05 ; ")
+ -- inefficient but non critical
+ local function slant_1(v,dx,dy,txt,xsign,ysign,loc,labloc)
+ if #v > 0 then
+ local l = { }
+ for kk, vv in ipairs(v) do
+ local h, k = vv.height, vv.kern
+ if h and k then
+ l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ end
+ context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1])
+ context("draw laddered (%s) withcolor .5white ;",table.concat(l,".."))
+ context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l])
+ for k, v in ipairs(l) do
+ context("draw %s withcolor blue withpen pencircle scaled 2lw ;",v)
+ end
+ end
+ end
+ local function slant_2(v,dx,dy,txt,xsign,ysign,loc,labloc)
+ if #v > 0 then
+ local l = { }
+ for kk, vv in ipairs(v) do
+ local h, k = vv.height, vv.kern
+ if h and k then
+ l[#l+1] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy)
+ end
+ end
+ if loc == "top" then
+ context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[#l])
+ else
+ context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1])
+ end
+ for kk, vv in ipairs(v) do
+ local h, k = vv.height, vv.kern
+ if h and k then
+ context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[kk])
+ end
+ end
+ end
+ end
+ if math then
+ local kerns = math.kerns
+ if kerns then
+ for _, slant in ipairs { slant_1, slant_2 } do
+ for k,v in pairs(kerns) do
+ if k == "top_right" then
+ slant(v,width+italic,0,k,1,1,"top","ulft")
+ elseif k == "bottom_right" then
+ slant(v,width,0,k,1,1,"bot","lrt")
+ elseif k == "top_left" then
+ slant(v,0,0,k,-1,1,"top","ulft")
+ elseif k == "bottom_left" then
+ slant(v,0,0,k,-1,1,"bot","lrt")
+ end
+ end
+ end
+ end
+ end
+ local function show(x,y,txt)
+ local xx, yy = x*factor, y*factor
+ context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy)
+ context('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy)
+ context('label.bot("(%s,%s)",(%s,%s+2bp)) ;',x,y,xx,yy)
+ end
+ if anchors then
+ local a = anchors.baselig
+ if a then
+ for k, v in pairs(a) do
+ for kk, vv in ipairs(v) do
+ show(vv[1],vv[2],k .. ":" .. kk)
+ end
+ end
+ end
+ local a = anchors.mark
+ if a then
+ for k, v in pairs(a) do
+ show(v[1],v[2],k)
+ end
+ end
+ local a = anchors.basechar
+ if a then
+ for k, v in pairs(a) do
+ show(v[1],v[2],k)
+ end
+ end
+ local ba = anchors.centry
+ if a then
+ for k, v in pairs(a) do
+ show(v[1],v[2],k)
+ end
+ end
+ local a = anchors.cexit
+ if a then
+ for k, v in pairs(a) do
+ show(v[1],v[2],k)
+ end
+ end
+ end
+ if italic ~= 0 then
+ context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury)
+ context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+italic,ury,width+italic,ury)
+ context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+italic,ury)
+ context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury)
+ context('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury)
+ end
+ if top_accent ~= 0 then
+ context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury)
+ context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury)
+ context('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury)
+ end
+ if bot_accent ~= 0 then
+ context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly)
+ context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury)
+ context('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly)
+ end
+ context('draw origin withcolor red withpen pencircle scaled 2lw;')
+ context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
+ context("currentpicture := currentpicture scaled 8 ;")
+ context.stopMPcode()
+ -- elseif c then
+ -- lastdata, lastunicode = nil, nil
+ -- local factor = (7200/7227)/65536
+ -- context.startMPcode()
+ -- context("pickup pencircle scaled .25bp ; ")
+ -- context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum)
+ -- context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;')
+ -- context("defaultscale := 0.05 ; ")
+ -- local italic, top_accent, bot_accent = (c.italic or 0)*factor, (c.top_accent or 0)*factor, (c.bot_accent or 0)*factor
+ -- local width, height, depth = (c.width or 0)*factor, (c.height or 0)*factor, (c.depth or 0)*factor
+ -- local ury = height
+ -- if italic ~= 0 then
+ -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury)
+ -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury)
+ -- context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height)
+ -- context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height)
+ -- context('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height)
+ -- end
+ -- if top_accent ~= 0 then
+ -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height)
+ -- context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height)
+ -- context('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height)
+ -- end
+ -- if bot_accent ~= 0 then
+ -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height)
+ -- context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height)
+ -- context('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height)
+ -- end
+ -- context('draw origin withcolor red withpen pencircle scaled 1bp;')
+ -- context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;")
+ -- context("currentpicture := currentpicture scaled 8 ;")
+ -- context.stopMPcode()
+ else
+ lastdata, lastunicode = nil, nil
+ context("no such shape: 0x%05X",charnum)
+ end
+ context.stop()
+end
+
+moduledata.fonts.shapes.showglyphshape = showglyphshape
+
+function moduledata.fonts.shapes.showallglypshapes(specification)
+ specification = interfaces.checkedspecification(specification)
+ local id, cs = fonts.definers.internal(specification,"<module:fonts:shapes:font>")
+ local descriptions = fontdata[id].descriptions
+ for unicode, description in fonts.iterators.descriptions(tfmdata) do
+ if unicode >= 0x110000 then
+ break
+ end
+ context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0)
+ showglyphshape { number = id, character = unicode }
+ context.modulefontsstopshowglyphshape()
+ end
+end
+
+function moduledata.fonts.shapes.showlastglyphshapefield(unicode,name)
+ if not descriptions then
+ -- bad news
+ elseif name == "unicode" then
+ context("U+%05X",descriptions.unicode)
+ else
+ local d = descriptions[name]
+ if d then
+ context(d)
+ end
+ end
+end
diff --git a/tex/context/modules/mkiv/s-fonts-shapes.mkiv b/tex/context/modules/mkiv/s-fonts-shapes.mkiv
new file mode 100644
index 000000000..c1e9d61d2
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-shapes.mkiv
@@ -0,0 +1,115 @@
+%D \module
+%D [ file=s-fonts-shapes, % s-fnt-29,
+%D version=2010.09.27,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Tracing Shapes,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[fonts-shapes]
+
+\registerctxluafile{s-fonts-shapes}{}
+
+\installmodulecommandluasingle \showfontshapes {moduledata.fonts.shapes.showlist}
+\installmodulecommandluasingle \showglyphshape {moduledata.fonts.shapes.showglypshape}
+\installmodulecommandluatwo \showlastglyphshapefield {moduledata.fonts.shapes.showlastglyphshapefield}
+\installmodulecommandluasingle \showallglyphshapes {moduledata.fonts.shapes.showallglypshapes}
+
+\let\modulefontsstartshowglyphshape\gobblethreearguments
+\let\modulefontsstopshowglyphshape \relax
+
+\unprotect
+
+\startsetups module:showallglyphshapes:start
+
+ \unexpanded\def\modulefontsstartshowglyphshape##1##2##3{
+ \startTEXpage[\c!offset=\exheight]
+ \edef\lastshownglyphshapefieldunicode{##1}%
+ \edef\lastshownglyphshapefieldname {##2}%
+ \edef\lastshownglyphshapefieldindex {##3}%
+ \raggedcenter
+ }
+
+ \unexpanded\def\modulefontsstopshowglyphshape {
+ \par
+ \doifsomething {\lastshownglyphshapefieldunicode} {
+ \begingroup
+ \dontleavehmode
+ \tttf
+ \setstrut
+ \strut
+ 0x\uchexnumbers\lastshownglyphshapefieldunicode
+ \space:\space
+ \lastshownglyphshapefieldname
+ \space:\space
+ \lastshownglyphshapefieldindex
+ \par
+ \endgroup
+ }
+ \stopTEXpage
+ }
+
+\stopsetups
+
+\protect
+
+% downward compatibility:
+
+\unexpanded\def\ShowGlyphShape#1#2#3% name size glyph
+ {\ctxlua{moduledata.fonts.shapes.showglyphshape { name = "#1", size = "#2", character = "#3" } }}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-shapes.mkiv}
+
+\setupbodyfont[dejavu,9pt]
+
+\setuplayout
+ [backspace=1cm,
+ topspace=1cm,
+ footer=1cm,
+ header=0cm,
+ height=middle,
+ width=middle]
+
+\setupfootertexts
+ []
+ [\saveddefinedfontname\quad\pagenumber]
+
+\starttext
+
+% \savedefinedfont[Bold*default]
+% \showfontshapes[number=\saveddefinedfontid]
+% \page
+
+% \showfontshapes[name=BoldItalic*default]
+% \page
+
+ % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x62A} \stopTEXpage
+ % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0x2004} \stopTEXpage
+ % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0xF0299} \stopTEXpage
+ % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{NameMe.1190} \stopTEXpage
+
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x00066}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D453}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D43F}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D444}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D447}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x02112}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D432}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D43D}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D44A}\stopTEXpage
+% \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D45D}\stopTEXpage
+% \page
+
+ % \showallglyphshapes[name=name:cambria-math,size=100bp]
+% \showallglyphshapes[name=name:dejavuserif,size=100bp]
+
+\showallglyphshapes[name=file:brill.otf,size=100bp]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-system.lua b/tex/context/modules/mkiv/s-fonts-system.lua
new file mode 100644
index 000000000..0c0ad4d86
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-system.lua
@@ -0,0 +1,68 @@
+if not modules then modules = { } end modules ['s-fonts-system'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-system.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- ["zapfinoforteltpro"]={
+-- ["designsize"]=0,
+-- ["familyname"]="zapfinoforteltpro",
+-- ["filename"]="zapfinoforteltpro.otf",
+-- ["fontname"]="zapfinoforteltpro",
+-- ["fontweight"]="regular",
+-- ["format"]="otf",
+-- ["fullname"]="zapfinoforteltpro",
+-- ["maxsize"]=0,
+-- ["minsize"]=0,
+-- ["modification"]=1105543074,
+-- ["modifiers"]="regular",
+-- ["rawname"]="ZapfinoForteLTPro",
+-- ["style"]="normal",
+-- ["subfamily"]="regular",
+-- ["variant"]="normal",
+-- ["weight"]="normal",
+-- ["width"]="normal",
+-- }
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.system = moduledata.fonts.system or { }
+
+local lower = string.lower
+
+local context = context
+local NC, NR, HL = context.NC, context.NR, context.HL
+local bold = context.bold
+
+function moduledata.fonts.system.showinstalled(specification)
+ specification = interfaces.checkedspecification(specification)
+ local pattern = lower(specification.pattern or "")
+ local list = fonts.names.list(pattern,false,true)
+ if list then
+ local files = { }
+ for k, v in next, list do
+ files[file.basename(string.lower(v.filename))] = v
+ end
+ context.starttabulate { "|Tl|Tl|Tl|Tl|Tl|Tl|" }
+ HL()
+ NC() bold("filename")
+ NC() bold("fontname")
+ NC() bold("subfamily")
+ NC() bold("variant")
+ NC() bold("weight")
+ NC() bold("width")
+ NC() NR()
+ HL()
+ for filename, data in table.sortedpairs(files) do
+ NC() context(filename)
+ NC() context(data.fontname)
+ NC() context(data.subfamily)
+ NC() context(data.variant)
+ NC() context(data.weight)
+ NC() context(data.width)
+ NC() NR()
+ end
+ context.stoptabulate()
+ end
+end
diff --git a/tex/context/modules/mkiv/s-fonts-system.mkiv b/tex/context/modules/mkiv/s-fonts-system.mkiv
new file mode 100644
index 000000000..6d9082a6b
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-system.mkiv
@@ -0,0 +1,39 @@
+%D \module
+%D [ file=s-fonts0system, % s-fnt-11,
+%D version=2006.02.01, % or so
+%D title=\CONTEXT\ Style File,
+%D subtitle=Listing Installed Fonts,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This code usd to be in the kernel but since it's hardly used
+%D it's now a module.
+%D
+%D \starttyping
+%D \showinstalledfonts[pattern={officinasans.*}]
+%D \showinstalledfonts[pattern={officinaserif.*}]
+%D \showinstalledfonts[pattern={officina.*itc.*}]
+%D \stoptyping
+
+\startmodule[fonts-system]
+
+\registerctxluafile{s-fonts-system}{}
+
+\installmodulecommandluasingle \showinstalledfonts {moduledata.fonts.system.showinstalled}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-system.mkiv}
+
+\usemodule[art-01] \setuplayout[overview] \setupbodyfont[7pt]
+
+\starttext
+
+ \showinstalledfonts
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-tables.lua b/tex/context/modules/mkiv/s-fonts-tables.lua
new file mode 100644
index 000000000..c32f4628c
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-tables.lua
@@ -0,0 +1,363 @@
+if not modules then modules = { } end modules ['s-fonts-tables'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-tables.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.tables = moduledata.fonts.tables or { }
+
+local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
+local sortedkeys = table.sortedkeys
+local format = string.format
+local concat = table.concat
+
+local tabletracers = moduledata.fonts.tables
+
+local context = context
+
+local digits = {
+ dflt = {
+ dflt = "1234567890 1/2",
+ },
+ arab = {
+ dflt = "",
+ },
+ latn = {
+ dflt = "1234567890 1/2",
+ }
+}
+
+local punctuation = {
+ dflt = {
+ dflt = ". , : ; ? ! ‹ › « »",
+ },
+}
+
+local symbols = {
+ dflt = {
+ dflt = "@ # $ % & * () [] {} <> + - = / |",
+ },
+}
+
+local LATN = "abcdefghijklmnopqrstuvwxyz"
+
+local uppercase = {
+ latn = {
+ dflt = LATN,
+ fra = LATN .. " ÀÁÂÈÉÊÒÓÔÙÚÛÆÇ",
+ },
+ grek = {
+ dftl = "ΑΒΓΔΕΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ",
+ },
+ cyrl= {
+ dflt = "АБВГДЕЖЗИІЙКЛМНОПРСТУФХЦЧШЩЪЫЬѢЭЮЯѲ"
+ },
+}
+
+local latn = "abcdefghijklmnopqrstuvwxyz"
+
+local lowercase = {
+ latn = {
+ dftl = latn,
+ nld = latn .. " ïèéë",
+ deu = latn .. " äöüß",
+ fra = latn .. " àáâèéêòóôùúûæç",
+ },
+ grek = {
+ dftl = "αβγδεηθικλμνξοπρστυφχψω",
+ },
+ cyrl= {
+ dflt = "абвгдежзиійклмнопрстуфхцчшщъыьѣэюяѳ"
+ },
+ arab = {
+ dflt = "ابجدهوزحطيكلمنسعفصقرشتثخذضظغ"
+ },
+}
+
+local samples = {
+ digits = digits,
+ punctuation = punctuation,
+ symbols = symbols,
+ uppercase = uppercase,
+ lowercase = lowercase,
+}
+
+tabletracers.samples = samples
+
+setmetatableindex(uppercase, function(t,k) return rawget(t,"latn") end)
+setmetatableindex(lowercase, function(t,k) return rawget(t,"latn") end)
+setmetatableindex(digits, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(symbols, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(punctuation, function(t,k) return rawget(t,"dflt") end)
+
+setmetatableindex(uppercase.latn, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(uppercase.grek, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(uppercase.cyrl, function(t,k) return rawget(t,"dflt") end)
+
+setmetatableindex(lowercase.latn, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(lowercase.grek, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(lowercase.cyrl, function(t,k) return rawget(t,"dflt") end)
+
+setmetatableindex(digits.dflt, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(symbols.dflt, function(t,k) return rawget(t,"dflt") end)
+setmetatableindex(punctuation.dflt, function(t,k) return rawget(t,"dflt") end)
+
+local function typesettable(t,keys,synonyms,nesting,prefix)
+ if t then
+ if not prefix then
+ context.starttabulate { "|Tl|Tl|Tl|" }
+ end
+ for k, v in sortedhash(keys) do
+ if k == "synonyms" then
+ elseif type(v) ~= "table" then
+ context.NC()
+ if prefix then
+ context("%s.%s",prefix,k)
+ else
+ context(k)
+ end
+ context.NC()
+ local tk = t[k]
+ if v == "boolean" then
+ context(tostring(tk or false))
+ elseif not tk then
+ context("<unset>")
+ elseif v == "filename" then
+ context(file.basename(tk))
+ elseif v == "basepoints" then
+ context("%sbp",tk)
+ elseif v == "scaledpoints" then
+ context("%p",tk)
+ elseif v == "table" then
+ context("<table>")
+ else -- if v == "integerscale" then
+ context(tostring(tk))
+ end
+ context.NC()
+ local synonym = (not prefix and synonyms[k]) or (prefix and synonyms[format("%s.%s",prefix,k)])
+ if synonym then
+ context(format("(%s)",concat(synonym," ")))
+ end
+ context.NC()
+ context.NR()
+ elseif nesting == false then
+ context("<table>")
+ else -- true or nil
+ typesettable(t[k],v,synonyms,nesting,k)
+ end
+ end
+ if not prefix then
+ context.stoptabulate()
+ end
+ end
+end
+
+local function typeset(t,keys,nesting,prefix)
+ local synonyms = keys.synonyms or { }
+ local collected = { }
+ for k, v in next, synonyms do
+ local c = collected[v]
+ if not c then
+ c = { }
+ collected[v] = c
+ end
+ c[#c+1] = k
+ end
+ for k, v in next, collected do
+ table.sort(v)
+ end
+ typesettable(t,keys,collected,nesting,prefix)
+end
+
+tabletracers.typeset = typeset
+
+function tabletracers.showproperties(nesting)
+ local tfmdata = fonts.hashes.identifiers[font.current()]
+ typeset(tfmdata.properties,fonts.constructors.keys.properties,nesting)
+end
+
+function tabletracers.showparameters(nesting)
+ local tfmdata = fonts.hashes.identifiers[font.current()]
+ typeset(tfmdata.parameters,fonts.constructors.keys.parameters,nesting)
+end
+
+function tabletracers.showpositionings()
+ local tfmdata = fonts.hashes.resources[font.current()]
+ local resources = tfmdata.resources
+ if resources then
+ local features = resources.features
+ if features then
+ local gpos = features.gpos
+ if gpos and next(gpos) then
+ context.starttabulate { "|Tl|Tl|Tlp|" }
+ for feature, scripts in sortedhash(gpos) do
+ for script, languages in sortedhash(scripts) do
+ context.NC()
+ context(feature)
+ context.NC()
+ context(script)
+ context.NC()
+ context(concat(sortedkeys(languages)," "))
+ context.NC()
+ context.NR()
+ end
+ end
+ context.stoptabulate()
+ else
+ context("no entries")
+ context.par()
+ end
+ end
+ end
+end
+
+local dynamics = true
+
+function tabletracers.showsubstitutions()
+ local tfmdata = fonts.hashes.identifiers[font.current()]
+ local resources = tfmdata.resources
+ if resources then
+ local features = resources.features
+ if features then
+ local gsub = features.gsub
+ if gsub then
+ local makes_sense = { }
+ for feature, scripts in sortedhash(gsub) do
+ for script, languages in sortedhash(scripts) do
+ for language in sortedhash(languages) do
+ local tag = format("dummy-%s-%s-%s",feature,script,language)
+ local fnt = format("file:%s*%s",file.basename(tfmdata.properties.filename),tag)
+ context.definefontfeature (
+ { tag },
+ {
+ mode = "node",
+ script = script,
+ language = language,
+ [feature] = "yes"
+ }
+ )
+ if not dynamics then
+ context.definefont( { fnt }, { fnt } )
+ end
+ makes_sense[#makes_sense+1] = {
+ feature = feature,
+ tag = tag,
+ script = script,
+ language = language,
+ fontname = fnt,
+ }
+ end
+ end
+ end
+ if #makes_sense > 0 then
+ context.starttabulate { "|Tl|Tl|Tl|p|" }
+ for i=1,#makes_sense do
+ local data = makes_sense[i]
+ local script = data.script
+ local language = data.language
+ context.NC()
+ context(data.feature)
+ context.NC()
+ context(script)
+ context.NC()
+ context(language)
+ context.NC()
+ if not dynamics then
+ context.startfont { data.fontname }
+ else
+ context.addff(data.tag)
+ end
+ context.verbatim(samples.lowercase [script][language]) context.par()
+ context.verbatim(samples.uppercase [script][language]) context.par()
+ context.verbatim(samples.digits [script][language]) context.par()
+ context.verbatim(samples.punctuation[script][language]) context.quad()
+ context.verbatim(samples.symbols [script][language])
+ if not dynamics then
+ context.stopfont()
+ end
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+ else
+ context("no entries")
+ context.par()
+ end
+ end
+ end
+ end
+end
+
+function tabletracers.showunicodevariants()
+
+ local variants = fonts.hashes.variants[true]
+
+ if variants then
+ context.starttabulate { "|c|c|c|c|c|c|c|" }
+ for selector, unicodes in sortedhash(variants) do
+ local done = false
+ for unicode, variant in sortedhash(unicodes) do
+ context.NC()
+ if not done then
+ context("%U",selector)
+ done = true
+ end
+ context.NC()
+ context("%U",unicode)
+ context.NC()
+ context("%c",unicode)
+ context.NC()
+ context("%U",variant)
+ context.NC()
+ context("%c",variant)
+ context.NC()
+ context("%c%c",unicode,selector)
+ context.NC()
+ context.startoverlay()
+ context("{\\color[trace:r]{%c}}{\\color[trace:ds]{%c}}",unicode,variant)
+ context.stopoverlay()
+ context.NC()
+ context.NR()
+ end
+ end
+ context.stoptabulate()
+ end
+
+end
+function tabletracers.showall(specification) -- not interfaced
+
+ specification = interfaces.checkedspecification(specification)
+
+ if specification.title then
+ context.starttitle { title = specification.title }
+ end
+
+ context.startsubject { title = "Properties" }
+ tabletracers.showproperties()
+ context.stopsubject()
+
+ context.startsubject { title = "Parameters" }
+ tabletracers.showparameters()
+ context.stopsubject()
+
+ context.startsubject { title = "Positioning features" }
+ tabletracers.showpositionings()
+ context.stopsubject()
+
+ context.startsubject { title = "Substitution features" }
+ tabletracers.showsubstitutions()
+ context.stopsubject()
+
+ context.startsubject { title = "Unicode variants" }
+ tabletracers.showunicodevariants()
+ context.stopsubject()
+
+ if title then
+ context.stoptitle()
+ end
+
+end
diff --git a/tex/context/modules/mkiv/s-fonts-tables.mkiv b/tex/context/modules/mkiv/s-fonts-tables.mkiv
new file mode 100644
index 000000000..64fe76f0e
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-tables.mkiv
@@ -0,0 +1,38 @@
+%D \module
+%D [ file=s-fonts-tables,
+%D version=2011.10.10,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Basic Font Data Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: make a mtxrun --script font <name> option
+
+\startmodule[fonts-tables]
+
+\registerctxluafile{s-fonts-tables}{}
+
+\installmodulecommandluasingle \showfonttables {moduledata.fonts.tables.showall}
+\installmodulecommandluasingle \showfontproperties {moduledata.fonts.tables.showproperties}
+\installmodulecommandluasingle \showfontparameters {moduledata.fonts.tables.showparameters}
+\installmodulecommandluasingle \showfontpositionings {moduledata.fonts.tables.showpositionings}
+\installmodulecommandluasingle \showfontsubstitutions {moduledata.fonts.tables.showsubstitutions}
+\installmodulecommandluasingle \showfontunicodevariants{moduledata.fonts.tables.showunicodevariants}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-tables.mkiv}
+
+\usemodule[art-01]
+
+\setupbodyfont
+ [cambria]
+
+\starttext
+ \showfonttables[title=Cambria]
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-vectors.lua b/tex/context/modules/mkiv/s-fonts-vectors.lua
new file mode 100644
index 000000000..af8042f84
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-vectors.lua
@@ -0,0 +1,104 @@
+if not modules then modules = { } end modules ['s-fonts-vectors'] = {
+ version = 1.001,
+ comment = "companion to s-fonts-vectors.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.fonts = moduledata.fonts or { }
+moduledata.fonts.protrusions = moduledata.fonts.protrusions or { }
+moduledata.fonts.expansions = moduledata.fonts.expansions or { }
+
+local NC, NR = context.NC, context.NR
+
+local classes = fonts.protrusions.classes
+local vectors = fonts.protrusions.vectors
+
+function moduledata.fonts.protrusions.showvector(specification)
+ specification = interfaces.checkedspecification(specification)
+ local vector = vectors[specification.name or "?"]
+ if vector then
+ context.blank()
+ context.startcolumns { n = specification.columns or 3, balance="yes" }
+ context.starttabulate { "|T||cw(.5em)||" }
+ for unicode, values in table.sortedhash(vector) do
+ NC() context("%U",unicode)
+ NC() context("%.02f",values[1])
+ NC() context("%c",unicode)
+ NC() context("%.02f",values[2])
+ NC() NR()
+ end
+ context.stoptabulate()
+ context.stopcolumns()
+ context.blank()
+ end
+end
+
+function moduledata.fonts.protrusions.showclass(specification)
+ specification = interfaces.checkedspecification(specification)
+ local class = specification.name and classes[specification.name]
+ local classes = class and { class} or classes
+ context.starttabulate { "|l|l|r|r|r|" }
+ NC() context.bold("name")
+ NC() context.bold("vector")
+ NC() context.bold("factor")
+ NC() context.bold("left")
+ NC() context.bold("right")
+ NC() NR()
+ for name, class in table.sortedhash(classes) do
+ NC() context(name)
+ NC() context(class.vector)
+ NC() context("%.02f",class.factor)
+ NC() context("%.02f",class.left)
+ NC() context("%.02f",class.right)
+ NC() NR()
+ end
+ context.stoptabulate()
+end
+
+local classes = fonts.expansions.classes
+local vectors = fonts.expansions.vectors
+
+function moduledata.fonts.expansions.showvector(specification)
+ specification = interfaces.checkedspecification(specification)
+ local vector = vectors[specification.name or "?"]
+ if vector then
+ context.blank()
+ context.startcolumns { n = specification.columns or 3, balance="yes" }
+ context.starttabulate { "|T|cw(.5em)||" }
+ for unicode, value in table.sortedhash(vector) do
+ NC() context("%U",unicode)
+ NC() context("%c",unicode)
+ NC() context("%.02f",value)
+ NC() NR()
+ end
+ context.stoptabulate()
+ context.stopcolumns()
+ context.blank()
+ end
+end
+
+function moduledata.fonts.expansions.showclass(specification)
+ specification = interfaces.checkedspecification(specification)
+ local class = specification.name and classes[specification.name]
+ local classes = class and { class} or classes
+ context.starttabulate { "|l|l|r|r|r|" }
+ NC() context.bold("name")
+ NC() context.bold("vector")
+ NC() context.bold("step")
+ NC() context.bold("factor")
+ NC() context.bold("stretch")
+ NC() context.bold("shrink")
+ NC() NR()
+ for name, class in table.sortedhash(classes) do
+ NC() context(name)
+ NC() context(class.vector)
+ NC() context("%.02f",class.step)
+ NC() context("%.02f",class.factor)
+ NC() context("% 2i",class.stretch)
+ NC() context("% 2i",class.shrink)
+ NC() NR()
+ end
+ context.stoptabulate()
+end
diff --git a/tex/context/modules/mkiv/s-fonts-vectors.mkiv b/tex/context/modules/mkiv/s-fonts-vectors.mkiv
new file mode 100644
index 000000000..2605fe964
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-vectors.mkiv
@@ -0,0 +1,72 @@
+%D \module
+%D [ file=s-fonts-vectors, % was s-fnt-51,
+%D version=2012.11.27,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Protrusion and Expansion,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This code is used in the \MKIV\ fonts manual.
+
+\startmodule[fonts-vectors]
+
+\registerctxluafile{s-fonts-vectors}{}
+
+\installmodulecommandluasingle \showprotrusionclass {moduledata.fonts.protrusions.showclass}
+\installmodulecommandluasingle \showprotrusionvector {moduledata.fonts.protrusions.showvector}
+\installmodulecommandluasingle \showexpansionclass {moduledata.fonts.expansions.showclass}
+\installmodulecommandluasingle \showexpansionvector {moduledata.fonts.expansions.showvector}
+
+\stopmodule
+
+\continueifinputfile{s-fonts-vectors.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \startsubject[title=protrusion]
+
+ \startsubsubject[title=class]
+ \showprotrusionclass
+ \stopsubsubject
+
+ \startsubsubject[title=vector pure]
+ \showprotrusionvector[name=pure]
+ \stopsubsubject
+
+ \startsubsubject[title=vector punctuation]
+ \showprotrusionvector[name=punctuation]
+ \stopsubsubject
+
+ \startsubsubject[title=vector alpha]
+ \showprotrusionvector[name=alpha]
+ \stopsubsubject
+
+ \startsubsubject[title=vector quality]
+ \showprotrusionvector[name=quality]
+ \stopsubsubject
+
+ \stopsubject
+
+ \page
+
+ \startsubject[title=expansion]
+
+ \startsubsubject[title=class]
+ \showprotrusionclass
+ \stopsubsubject
+
+ \startsubsubject[title=vector quality]
+ \showprotrusionvector[name=quality]
+ \stopsubsubject
+
+ \stopsubject
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/s-inf-01.mkvi b/tex/context/modules/mkiv/s-inf-01.mkvi
new file mode 100644
index 000000000..2c0c1681e
--- /dev/null
+++ b/tex/context/modules/mkiv/s-inf-01.mkvi
@@ -0,0 +1,260 @@
+%D \module
+%D [ file=s-inf-01,
+%D version=2009.07.09,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Information 1 (\MKII/\MKIV\ usage),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Some day I will generalize this table mechanism. This list is only
+%D right when run in the minimals as my machine might have more files.
+%D
+%D Als, the remaining tex code can proably be lua also which is more
+%D consistent.
+%D
+%D \starttyping
+%D context auto:s-inf-01
+%D context auto:s-inf-01 --basepath=t:/texmf/tex/context/base
+%D \stoptyping
+
+% \enabletrackers[context.*]
+
+\startluacode
+ local format, gsub, find, match = string.format, string.gsub, string.find, string.match
+
+ local list, size, comp, used, nope = { }, { }, { }, { mkii = { }, mkiv = { }, mkvi = { } }, { 0, 0, 0, 0, 0 }
+
+ local omit = {
+ "char%-def%.lua",
+ "mult%-def%.lua", "mult%-..%.mkii", "mult%-m..%.mkii",
+ }
+ local skip = {
+ "prag%-.*%.tex", "docs%-.*.tex", "list%-.*%.tex", "test%-.*%.tex", "demo%-.*%.tex",
+ "opti%-.*%.tex", "chrt%-.*%.tex", ".*%-old", ".*%-obs", ".*%-tst", "supp%-.*%.tex",
+ "colo%-pan.tex", ".*test.*"
+ }
+ local types = {
+ "tex", "mkii", "mkiv", "mkvi", "lua"
+ }
+ local patterns = {
+ "^([a-z][a-z][a-z][a-z])%-[a-z0-9%-]+%.[a-z]+",
+ "^([xms])%-[a-z0-9%-]+%.[a-z]+",
+ }
+
+ local function collect(list,suffix,n)
+ local path = document.arguments.basepath or file.dirname(resolvers.find_file("context.mkiv"),".")
+ local pattern = path .. "/*." .. suffix .. "$" -- avoid bla.tex~
+ local texfiles = dir.glob(pattern)
+ for i=1,#texfiles do
+ local name = texfiles[i]
+ local base = file.basename(name)
+ for p=1,#patterns do
+ local category = match(base,patterns[p])
+ if category and lfs.isfile(name) then
+ local okay = true
+ for s=1,#skip do
+ if find(base,skip[s]) then
+ okay = false
+ break
+ end
+ end
+ if okay then
+ local lm, sm, cm = list[category], size[category], comp[category]
+ if not lm then
+ lm, sm, cm = { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }
+ list[category], size[category], comp[category] = lm, sm, cm
+ end
+ lm[n] = lm[n] + 1
+ local done = true
+ for o=1,#omit do
+ if find(base,omit[o]) then
+ done = false
+ break
+ end
+ end
+ local data = io.loaddata(name)
+ if data then
+ if suffix == "lua" then
+ data = gsub(data,"%-%-%[%[.-%]%]%-%-","")
+ data = gsub(data,"%-%-.-[\n\r]","")
+ else
+ data = gsub(data,"%%.-[\n\r]","")
+ end
+ data = gsub(data,"%s","")
+ else
+ logs.report("error","unknown file %a",name)
+ data = ""
+ end
+ sm[n+5] = sm[n+5] + #data
+ if done then
+ sm[n] = sm[n] + #data
+ else
+ cm[n] = cm[n] + 1
+ end
+ end
+ end
+ end
+ end
+ end
+
+ local function prepare(what)
+ if next(list) then
+ -- already loaded
+ else
+ for i=1,#types do
+ collect(list,types[i],i)
+ end
+ for category in next, list do
+ pattern ="{"..category.."%-"
+ for suffix, t in next, used do
+ local data = io.loaddata(resolvers.find_file("context."..suffix))
+ if data and find(data,pattern) then
+ t[category] = true
+ end
+ end
+ end
+ end
+ local max, what = 0, (what == "size" and size) or list
+ for k, v in table.sortedpairs(what) do
+ for i=1,5 do if v[i] > max then max = v[i] end end
+ end
+ return max, what, function(n) return (max == 0 and 0) or (n == 0 and 0) or n/max end
+ end
+
+ local f_norm = string.formatters["%0.3f"]
+
+ function document.context_state_1(what)
+ local max, what, norm = prepare(what)
+ context.starttabulate { "|Tl|T|T|T|T|T|" }
+ context.NC()
+ context(category)
+ context.NC()
+ for i=1,#types do
+ local n, m = 0, 0
+ for k, v in next, list do
+ local nn, mm = what[k][i], what[k][i+5]
+ n = n + nn
+ m = m + (mm or nn)
+ end
+ context.Top(types[i],norm(max),n,m)
+ context.NC()
+ end
+ context.NC()
+ context.NR()
+ context.HL()
+ for k, v in table.sortedpairs(what) do
+ local c = what == size and comp[k] or nope
+ context.NC()
+ context("%s~%s~~%s~~%s",
+ (used.mkii[k] and "ii") or "~~",
+ (used.mkiv[k] and "iv") or "~~",
+ (used.mkvi[k] and "vi") or "~~",
+ k
+ )
+ -- context("%s\\enspace %s\\quad %s\\quad %s",
+ -- (used.mkii[k] and "ii") or "\\quad",
+ -- (used.mkiv[k] and "iv") or "\\quad",
+ -- (used.mkvi[k] and "vi") or "\\quad",
+ -- k
+ -- )
+ context.NC()
+ for i=1,#types do
+ context.Bar(types[i],v[i],c[i],f_norm(norm(v[i])))
+ context.NC()
+ end
+ context.NR()
+ end
+ context.stoptabulate()
+ end
+
+ function document.context_state_2(what)
+ local max, what, norm = prepare(what)
+ for k, v in table.sortedpairs(what) do
+ local c = (what == size and comp[k]) or nope
+ context.StartUp(k)
+ for i=1,#types do
+ context.Up(types[i],f_norm(norm(v[i])))
+ end
+ context.StopUp()
+ end
+ end
+
+\stopluacode
+
+\definecolor[bar:tex] [middlegreen]
+\definecolor[bar:mkii][middleblue]
+\definecolor[bar:mkiv][middlered]
+\definecolor[bar:mkvi][middleyellow]
+\definecolor[bar:lua] [middlegray]
+
+\newcount\UpCounter
+
+\starttexdefinition Top #what#fraction#total#bigones
+ \hbox to 5em{\hss#total}%
+ \enspace
+ \hbox {#what\ifnum#total=#bigones\else~#bigones\rlap{~+}\fi\hss}%
+\stoptexdefinition
+
+\starttexdefinition Bar #color#size#nobigones#fraction
+ \ifcase#size\else
+ \hbox to 5em{\hss\ifcase#nobigones\else\llap{-~}\fi#size}%
+ \enspace
+ \blackrule[color=bar:#color,width=#fraction\dimexpr 20em\relax,height=.8\strutht]%
+ \fi
+\stoptexdefinition
+
+\starttexdefinition StartUp #name
+ \def\UpName{#name}%
+ \dontleavehmode\framed[frame=off,align={middle,low},height=18em]\bgroup
+\stoptexdefinition
+
+\starttexdefinition StopUp
+ \par\nointerlineskip\blackrule[height=1pt,width=5em,depth=0pt,color=darkgray]
+ \par\tttf\strut\UpName\par
+ \egroup
+ \ifnum\UpCounter=17
+ \par \UpCounter\zerocount
+ \else
+ \kern1em \advance\UpCounter\plusone
+ \fi
+\stoptexdefinition
+
+\starttexdefinition Up #color#width
+ \scratchdimen#width\dimexpr 16em\relax
+ \ifdim\scratchdimen=\zeropoint
+ \kern1em
+ \else
+ \ifdim\scratchdimen<\onepoint \scratchdimen\onepoint \fi
+ \blackrule[color=bar:#color,height=\scratchdimen,width=1em]%
+ \fi
+\stoptexdefinition
+
+\starttexdefinition Show #title#how#what
+ \startTEXpage[offset=1em,width=fit]
+ \hbox{\tttf\strut\currentdate~-~#title}
+ \par
+ \ctxlua{document.context_state_\number#how("#what")}
+ \stopTEXpage
+\stoptexdefinition
+
+% \continueifinputfile{s-inf-01.mkvi}
+
+\starttext
+ \Show
+ {The number of files used in ConTeXt (base modules and styles).}
+ {1}{number}
+ \Show
+ {The size of (core) files used in ConTeXt (- indicates exclusion of large data files; + indicates inclusion of large data files; comment and spaces removed.)}
+ {1}{size}
+ \Show
+ {The relative number of files used in ConTeXt (tex, mkii, mkiv, mkvi, lua).}
+ {2}{number}
+ \Show
+ {The relative size of files used in ConTeXt (tex, mkii, mkiv, mkvi, lua).}
+ {2}{size}
+\stoptext
diff --git a/tex/context/modules/mkiv/s-inf-02.mkiv b/tex/context/modules/mkiv/s-inf-02.mkiv
new file mode 100644
index 000000000..cf8d572bc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-inf-02.mkiv
@@ -0,0 +1,27 @@
+%D \module
+%D [ file=s-inf-02,
+%D version=2009.11.25,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Information 2 (filenames),
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\starttext
+
+\starttabulate [|T|T|]
+ \NC \type{\jobname} \NC \jobname \NC \NR
+ \NC \type{\jobfilename} \NC \jobfilename \NC \NR
+ \NC \type{\jobfilesuffix} \NC \jobfilesuffix \NC \NR
+ \NC \type{\inputfilename} \NC \inputfilename \NC \NR
+ \NC \type{\inputfilebarename} \NC \inputfilebarename \NC \NR
+ \NC \type{\inputfilesuffix} \NC \inputfilesuffix \NC \NR
+ \NC \type{\outputfilename} \NC \outputfilename \NC \NR
+ \NC \type{\operatingsystem} \NC \operatingsystem \NC \NR
+\stoptabulate
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-inf-03.mkiv b/tex/context/modules/mkiv/s-inf-03.mkiv
new file mode 100644
index 000000000..a253bed77
--- /dev/null
+++ b/tex/context/modules/mkiv/s-inf-03.mkiv
@@ -0,0 +1,372 @@
+% \nopdfcompression
+
+% \starttext
+% There is a loop somewhere ... todo.
+% \stoptext
+
+\enablemode[tablet] % whatever that means
+
+\setupbodyfont[dejavu]
+
+\doifelsemode {tablet} {
+
+ \setuppapersize
+ [S6,landscape]
+ [S6,landscape]
+
+ \definefont
+ [TitlePageFont]
+ [MonoBold at 15pt]
+
+ \setupbodyfont
+ [tt,8pt]
+
+} {
+
+ \definefont
+ [TitlePageFont]
+ [MonoBold at 18pt]
+
+ \setupbodyfont
+ [tt]
+
+}
+
+\setuplayout
+ [header=0cm,
+ footer=1cm,
+ backspace=.5cm,
+ topspace=.5cm,
+ width=middle,
+ height=middle]
+
+\setuphead
+ [title]
+ [style=\ttc,
+ interaction=reference]
+
+\definehead
+ [xtitle]
+ [title]
+
+\setuphead
+ [xtitle]
+ [color=darkgreen]
+
+\setupfootertexts
+ [\llap{\goto{\hbox to 5cm{\hss previous}}[previouspage]}%
+ \quad\pagenumber\quad
+ \rlap{\goto{\hbox to 5cm{next\hss}}[nextpage]}]
+
+\setupinteraction
+ [state=start,
+ style=,
+ color=,
+ title={ConTeXt MkIV},
+ subtitle={Lua modules and functions},
+ author={Hans Hagen - automatically generated},
+ contrastcolor=]
+
+\setupinteractionscreen
+ [option=bookmark]
+
+\placebookmarks
+ [title,xtitle]
+ [force=yes]
+
+\definecolor[darkyellow][r=.5,g=.5,b=0]
+\definecolor[darkgray] [s=.15]
+
+\nonknuthmode
+
+\starttext
+
+\startbuffer
+\startluacode
+local basiclua = libraries.basiclua
+local basictex = libraries.basictex
+local extratex = libraries.extratex
+local extralua = libraries.extralua
+local obsolete = libraries.obsolete
+
+local find = string.find
+local color, gotolocation = context.color, context["goto"]
+
+for k, v in table.sortedpairs(_G) do
+ if obsolete[k] or find(k,"_") or k == "arg" or k == "utf" then
+ --
+ elseif basiclua[k] then
+ gotolocation(function() color( { "darkred" }, k) end, { k } )
+ elseif extralua[k] then
+ gotolocation(function() color( { "darkgreen" }, k) end, { k } )
+ elseif basictex[k] then
+ gotolocation(function() color( { "darkblue" }, k) end, { k } )
+ elseif extratex[k] then
+ gotolocation(function() color( { "darkyellow" }, k) end, { k } )
+ elseif type(v) == "table" then
+ gotolocation(function() color( { "white" }, k) end, { k } )
+ end
+ context(" ")
+end
+\stopluacode
+\stopbuffer
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkgray,
+ backgroundoffset=2mm]
+
+\startpagemakeup
+ \vfill
+ \pagereference[global]
+ \startnarrower[10mm]
+ \setupalign[nothyhenated,middle,broad]
+ \TitlePageFont \setupinterlinespace
+ \getbuffer % luabuffer
+ \par
+ \stopnarrower
+ \vfill
+ \vfill
+ \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\ttbf\white\ConTeXt\ MkIV}
+ \par
+ % \hskip10mm\scale[width=\dimexpr\paperwidth-20mm\relax]{\white \strut Lua infrastructure \emdash\ \currentdate}
+ \vfill
+\stoppagemakeup
+
+\setupbackgrounds
+ [page]
+ [background=]
+
+\startluacode
+local builtin = libraries.builtin
+local globals = libraries.globals
+local basiclua = libraries.basiclua
+local basictex = libraries.basictex
+local extratex = libraries.extratex
+local extralua = libraries.extralua
+local obsolete = libraries.obsolete
+
+local sortedkeys = table.sortedkeys
+local mark = storage.mark
+local marked = storage.marked
+local gsub = string.gsub
+local sub = string.sub
+local byte = string.byte
+local upper = string.upper
+
+local skipglobal = table.tohash {
+ "_G", "_M", "_ENV", "",
+ "context", "modules", "global", "arg", "utf", 1,
+ "_ptbs_", "_pcol_", "_plib_", "_clib_", "_tlib_",
+ "kpse", "commands",
+}
+
+local skipkeys = table.tohash {
+ "_pcol_", "_plib_", "_clib_", "_tlib_", "_bpnf_", "_ptbs_",
+ "_cldf_", "_cldn_", "_cldo_",
+ "_clmb_", "_clme_", "_clmm_", "_clmn_", "_clma_", "_clmh_",
+ "_G", "_M", "_ENV", "",
+ -- "global", "shortcuts",
+ "_VERSION", "_COPYRIGHT", "_DESCRIPTION", "_NAME", "_PACKAGE", "__unload",
+}
+
+local sameglobal = {
+ ["global"] = "_G",
+ -- ["commands"] = "cs", -- already gone
+}
+
+-- -- -- -- -- -- -- -- -- -- -- -- --
+-- this should be done internally
+-- -- -- -- -- -- -- -- -- -- -- -- --
+
+for k,v in next, modules do
+ mark(v)
+end
+
+mark(document.arguments)
+mark(environment.arguments)
+mark(environment.engineflags)
+mark(characters.data)
+
+-- -- -- -- -- -- -- -- -- -- -- -- --
+-- -- -- -- -- -- -- -- -- -- -- -- --
+
+local variant = 1 -- all parents
+local variant = 2 -- parent name too
+local variant = 3 -- no parents
+
+local done = { }
+
+local function childtables(key,tab,handler,depth)
+ depth = depth or 1
+ local keys = sortedkeys(tab) -- no sorted_pairs
+ for i=1,#keys do
+ local k = keys[i]
+-- if k ~= "_G" and k ~= "_M" and type(k) == "string" then
+ if not skipkeys[k] and type(k) == "string" then
+ local v = tab[k]
+ local t = type(v)
+ local s = k
+ if variant ~= 3 then
+ s = key and (key .. "." .. s) or s
+ end
+ if t == "table" then
+ if marked(v) then
+ t = "data"
+ handler(s,t,depth)
+ else
+if done[v] then
+ -- logs.report("inf-03","key %a in %a already done",k,v)
+else
+ done[v] = true
+ handler(s,t,depth)
+ if variant == 3 then
+ childtables(false,v,handler,depth+1)
+ elseif variant == 2 then
+ childtables(k,v,handler,depth+1)
+ else
+ childtables(s,v,handler,depth+1)
+ end
+ end
+end
+ else
+ handler(s,t,depth)
+ end
+ end
+ end
+end
+
+local NC, NR = context.NC, context.NR
+local overstrike, rlap, bf = context.overstrike, context.rlap, context.bf
+local color, gotolocation = context.color, context["goto"]
+
+local function cleanup(s)
+ return "\\char" ..byte(s) .. " "
+end
+
+local function handler(k,t,depth)
+ k = gsub(k,"([~#$%%^&{}\\|])",cleanup)
+ NC() rlap("\\quad\\tx\\kern" .. (depth or 0).. "em" .. upper(sub(t,1,1)) .. " ".. k) NC() NC() NR()
+end
+
+local function show(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
+ -- todo: table as argument
+-- print(title,subtitle,alias,builtin,t,lib,libcolor,glo,glocolor,mark,obsolete)
+ local keys = sortedkeys(t) -- no sorted_pairs
+ if #keys > 0 then
+ local fulltitle = title
+ if subtitle and subtitle ~= "" then
+ fulltitle = fulltitle .. " (" .. subtitle .. ")"
+ end
+ if alias and alias ~= "" then
+ fulltitle = fulltitle .. " (alias: " .. alias .. ")"
+ end
+ if builtin then
+ context.startxtitle { reference = title, title = fulltitle, backreference = "global" }
+ else
+ context.starttitle { reference = title, title = fulltitle, backreference = "global" }
+ end
+ context.startcolumns { n = 2 }
+ context.starttabulate { "|||" }
+ local t_obsolete = t.obsolete
+ if type(t_obsolete) ~= "table" then
+ t_obsolete = nil
+ end
+ for i=1,#keys do
+ local k = keys[i]
+ local v = t[k]
+ if k and k ~= "obsolete" and not skipkeys[k] and (not obsolete or not obsolete[k]) then
+ local inlib = lib and lib[k]
+ local inglo = glo and glo[k]
+ local t = type(v)
+ local kstr, tstr = k, t
+ local obs = t_obsolete and t_obsolete[k]
+ if obs then
+ tstr = function() overstrike(t) end
+ kstr = function() overstrike(k) end
+ end
+ local marked = marked(v)
+ if marked then
+ tstr = "data table"
+ end
+ if t == "table" then
+ local m = getmetatable(v)
+ if m and m.__call then
+ tstr = "function"
+ end
+ end
+ if not mark then
+ --
+ elseif inlib and tostring(inlib) ~= tostring(v) then
+ tstr = "overloaded ".. tstr
+ elseif inglo and tostring(inglo) ~= tostring(v) then
+ tstr = "overloaded ".. tstr
+ end
+ NC() bf()
+ if inlib then
+ if not mark and t == "table" then
+ gotolocation(function() color( { libcolor }, kstr) end, { k } )
+ else
+ color( { libcolor }, kstr)
+ end
+ elseif inglo then
+ if not mark and t == "table" then
+ gotolocation(function() color( { glocolor }, kstr) end, { k } )
+ else
+ color( { glocolor }, kstr)
+ end
+ else
+ if not mark and t == "table" then
+ gotolocation(k, { kstr } )
+ else
+ context(kstr)
+ end
+ end
+ NC()
+ if inlib then
+ color( { libcolor }, tstr)
+ elseif inglo then
+ color( { glocolor }, tstr)
+ else
+ context(tstr)
+ end
+ NC() NR()
+ if mark and t == "table" and title ~= "libraries" and title ~= "package" and not marked then
+ childtables(false,v,handler) -- (k,v,handler)
+ end
+ end
+ end
+ context.stoptabulate()
+ context.stopcolumns()
+ if builtin then
+ context.stopxtitle()
+ else
+ context.stoptitle()
+ end
+ end
+end
+
+show("global","",sameglobal.global,false,_G,builtin,"darkgreen",globals,"darkblue",false,obsolete)
+
+-- inspect(table.sortedkeys(context))
+
+for k, v in table.sortedpairs(_G) do
+ if not skipglobal[k] and not obsolete[k] and type(v) == "table" and not marked(v) then
+
+ -- local mt = getmetatable(v)
+ -- print("!!!!!!!!!!",k,v,mt,mt and mt.__index)
+
+ if basiclua[k] then show(k,"basic lua",sameglobal[k],basiclua[k],v,builtin[k],"darkred", false,false,true)
+ elseif extralua[k] then show(k,"extra lua",sameglobal[k],extralua[k],v,builtin[k],"darkred", false,false,true)
+ elseif basictex[k] then show(k,"basic tex",sameglobal[k],basictex[k],v,builtin[k],"darkred", false,false,true)
+ elseif extratex[k] then show(k,"extra tex",sameglobal[k],extratex[k],v,builtin[k],"darkred", false,false,true)
+ else
+ show(k,"context", sameglobal[k],false, v,builtin[k],"darkyellow",false,false,true)
+ end
+ end
+end
+
+\stopluacode
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-inf-04.mkiv b/tex/context/modules/mkiv/s-inf-04.mkiv
new file mode 100644
index 000000000..862bed72f
--- /dev/null
+++ b/tex/context/modules/mkiv/s-inf-04.mkiv
@@ -0,0 +1,48 @@
+\usemodule[art-01]
+
+\setupbodyfont[10pt]
+
+\starttext
+
+ \startluacode
+
+ context.subject("Configuration files")
+
+ local configurations = resolvers.instance.specification
+
+ context.starttabulate { "|Tl|Tl|" }
+ for i=1,#configurations do
+ context.NC()
+ context(i)
+ context.NC()
+ context.verbatim(resolvers.resolve(configurations[i]))
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+
+ local list = resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+
+ context.subject("Configuration paths")
+
+ -- context.verbatim(resolvers.luacnfspec)
+
+ context.starttabulate { "|Tl|Tl|" }
+ for i=1,#list do
+ local li = resolvers.resolve(list[i])
+ context.NC()
+ if lfs.isdir(li) then
+ context("-")
+ else
+ context("+")
+ end
+ context.NC()
+ context.verbatim(li)
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+
+ \stopluacode
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-counters.lua b/tex/context/modules/mkiv/s-languages-counters.lua
new file mode 100644
index 000000000..436e64a64
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-counters.lua
@@ -0,0 +1,52 @@
+if not modules then modules = { } end modules ['s-languages-counters'] = {
+ version = 1.001,
+ comment = "companion to s-languages-counters.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.counters = moduledata.languages.counters or { }
+
+local data = converters.verbose.data
+
+function moduledata.languages.counters.showverbose(specification)
+ specification = interfaces.checkedspecification(specification)
+ local list = utilities.parsers.settings_to_array(specification.language or "")
+ if #list == 0then
+ return
+ end
+ local used = { }
+ local words = { }
+ for i=1,#list do
+ local ai = list[i]
+ local di = data[ai]
+ if di and di.words then
+ used[#used+1] = ai
+ table.merge(words,di.words)
+ end
+ end
+ context.starttabulate { string.rep("|l",#used) .. "|r|" }
+ context.HL()
+ context.NC()
+ for i=1,#used do
+ context.bold(used[i])
+ context.NC()
+ end
+ context.bold("number")
+ context.NC()
+ context.NR()
+ context.HL()
+ for k, v in table.sortedhash(words) do
+ context.NC()
+ for i=1,#used do
+ context(data[used[i]].words[k] or "")
+ context.NC()
+ end
+ context(k)
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+end
diff --git a/tex/context/modules/mkiv/s-languages-counters.mkiv b/tex/context/modules/mkiv/s-languages-counters.mkiv
new file mode 100644
index 000000000..fa938d65a
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-counters.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=s-languages-counters, % s-lan-05,
+%D version=2011.05.01, % older
+%D title=\CONTEXT\ Style File,
+%D subtitle=Language Counters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[languages-counters]
+
+\registerctxluafile{s-languages-counters}{}
+
+\installmodulecommandluasingle \showverbosecounters {moduledata.languages.counters.showverbose}
+
+\stopmodule
+
+\continueifinputfile{s-languages-counters.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showverbosecounters[language={en,es}]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-frequencies.lua b/tex/context/modules/mkiv/s-languages-frequencies.lua
new file mode 100644
index 000000000..16213a412
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-frequencies.lua
@@ -0,0 +1,33 @@
+if not modules then modules = { } end modules ['s-languages-frequencies'] = {
+ version = 1.001,
+ comment = "companion to s-languages-frequencies.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.frequencies = moduledata.languages.frequencies or { }
+
+function moduledata.languages.frequencies.showlist(specification)
+ specification = interfaces.checkedspecification(specification)
+ local t = languages.frequencies.getdata(specification.language or languages.current())
+ context.starttabulate { "|lT|cw(2em)|r|" }
+ context.NC()
+ context.formatted.rlap("%s: %p",t.language,languages.frequencies.averagecharwidth(t.language))
+ context.NC()
+ context.NC()
+ context.NR()
+ context.HL()
+ for k, v in table.sortedhash(t.frequencies) do
+ context.NC()
+ context("%U",k)
+ context.NC()
+ context("%c",k)
+ context.NC()
+ context("%0.3f",v)
+ context.NC()
+ context.NR()
+ end
+ context.stoptabulate()
+end
diff --git a/tex/context/modules/mkiv/s-languages-frequencies.mkiv b/tex/context/modules/mkiv/s-languages-frequencies.mkiv
new file mode 100644
index 000000000..01a1f5682
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-frequencies.mkiv
@@ -0,0 +1,38 @@
+%D \module
+%D [ file=s-languages-frequencies, % s-lan-06,
+%D version=2013.03.22,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Language Frequencies,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[languages-frequencies]
+
+\registerctxluafile{s-languages-frequencies}{}
+
+\installmodulecommandluasingle \showfrequencies {moduledata.languages.frequencies.showlist}
+
+\stopmodule
+
+\continueifinputfile{s-languages-frequencies.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \hsize65\averagecharwidth \the\hsize: \input ward \par
+
+ \showfrequencies \page
+
+ \mainlanguage[de]
+
+ \hsize65\averagecharwidth \the\hsize: \input ward \par
+
+ \showfrequencies \page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-hyphenation.lua b/tex/context/modules/mkiv/s-languages-hyphenation.lua
new file mode 100644
index 000000000..c5a4f91f1
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-hyphenation.lua
@@ -0,0 +1,135 @@
+if not modules then modules = { } end modules ['s-languages-hyphenation'] = {
+ version = 1.001,
+ comment = "companion to s-languages-hyphenation.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.hyphenation = moduledata.languages.hyphenation or { }
+
+local a_colormodel = attributes.private('colormodel')
+
+local nodecodes = nodes.nodecodes
+local nodepool = nodes.pool
+local disc_code = nodecodes.disc
+local glyph_code = nodecodes.glyph
+local emwidths = fonts.hashes.emwidths
+local exheights = fonts.hashes.exheights
+local newkern = nodepool.kern
+local newrule = nodepool.rule
+local newglue = nodepool.glue
+
+local insert_node_after = node.insert_after
+local traverse_by_id = node.traverse_id
+local hyphenate = languages.hyphenators.handler -- lang.hyphenate
+local find_tail = node.tail
+local remove_node = nodes.remove
+
+local tracers = nodes.tracers
+local colortracers = tracers and tracers.colors
+local setnodecolor = colortracers.set
+
+local function identify(head,marked)
+ local current, prev = head, nil
+ while current do
+ local id = current.id
+ local next = current.next
+ if id == disc_code then
+ if prev and next then -- and next.id == glyph_code then -- catch other usage of disc
+ marked[#marked+1] = prev
+ end
+ elseif id == glyph_code then
+ prev = current
+ end
+ current = next
+ end
+end
+
+local function strip(head,marked)
+ for i=1,#marked do
+ local prev = marked[i]
+ remove_node(head,prev.next,true)
+ end
+end
+
+local function mark(head,marked,w,h,d,how)
+ for i=1,#marked do
+ local prev = marked[i]
+ local font = prev.font
+ local em = emwidths[font]
+ local ex = exheights[font]
+ local width = w*em
+ local rule = newrule(width,h*ex,d*ex)
+ head, prev = insert_node_after(head,prev,newkern(-width/2))
+ head, prev = insert_node_after(head,prev,rule)
+ head, prev = insert_node_after(head,prev,newkern(-width/2))
+ head, prev = insert_node_after(head,prev,newglue(0))
+ setnodecolor(rule,how,prev[a_colormodel])
+ end
+end
+
+local langs, tags, noflanguages = { }, { }, 0
+
+local colorbytag = false
+
+function moduledata.languages.hyphenation.showhyphens(head)
+ if noflanguages > 0 then
+ local marked = { }
+ for i=1,noflanguages do
+ local m = { }
+ local l = langs[i]
+ marked[i] = m
+ for n in traverse_by_id(glyph_code,head) do
+ n.lang = l
+ end
+ languages.hyphenators.methods.original(head)
+ identify(head,m)
+ strip(head,m)
+ end
+ for i=noflanguages,1,-1 do
+ local l = noflanguages - i + 1
+ mark(head,marked[i],1/16,l/2,l/4,"hyphenation:"..(colorbytag and tags[i] or i))
+ end
+ return head, true
+ else
+ return head, false
+ end
+end
+
+local savedlanguage
+
+function moduledata.languages.hyphenation.startcomparepatterns(list)
+ if list and list ~= "" then
+ tags = utilities.parsers.settings_to_array(list)
+ end
+ savedlanguage = tex.language
+ tex.language = 0
+ noflanguages = #tags
+ for i=1,noflanguages do
+ langs[i] = tags[i] and languages.getnumber(tags[i])
+ end
+ nodes.tasks.enableaction("processors","moduledata.languages.hyphenation.showhyphens")
+end
+
+function moduledata.languages.hyphenation.stopcomparepatterns()
+ noflanguages = 0
+ tex.language = savedlanguage or tex.language
+ nodes.tasks.disableaction("processors","moduledata.languages.hyphenation.showhyphens")
+end
+
+function moduledata.languages.hyphenation.showcomparelegend(list)
+ if list and list ~= "" then
+ tags = utilities.parsers.settings_to_array(list)
+ end
+ for i=1,#tags do
+ if i > 1 then
+ context.enspace()
+ end
+ context.color( { "hyphenation:"..(colorbytag and tags[i] or i) }, tags[i])
+ end
+end
+
+nodes.tasks.appendaction("processors","before","moduledata.languages.hyphenation.showhyphens")
+nodes.tasks.disableaction("processors","moduledata.languages.hyphenation.showhyphens")
diff --git a/tex/context/modules/mkiv/s-languages-hyphenation.mkiv b/tex/context/modules/mkiv/s-languages-hyphenation.mkiv
new file mode 100644
index 000000000..6662dbf2f
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-hyphenation.mkiv
@@ -0,0 +1,77 @@
+%D \module
+%D [ file=s-languages-hyphenation, % s-lan-04,
+%D version=2011.05.01,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Language Hyphenation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D For Mojca.
+
+\startmodule[languages-hyphenation]
+
+\registerctxluafile{s-languages-hyphenation}{}
+
+\unprotect
+
+\unexpanded\def\startcomparepatterns
+ {\dosingleempty\module_languages_hyphenation_start}
+
+\unexpanded\def\module_languages_hyphenation_start[#1]%
+ {\begingroup
+ \par
+ % \language\zerocount
+ % \setupalign[\v!nothyphenated]%
+ \ctxlua{moduledata.languages.hyphenation.startcomparepatterns("#1")}}
+
+\unexpanded\def\stopcomparepatterns
+ {\par
+ \ctxlua{moduledata.languages.hyphenation.stopcomparepatterns()}%
+ \endgroup}
+
+\installmodulecommandluasingle \showcomparepatternslegend {moduledata.languages.hyphenation.showcomparelegend}
+
+\protect
+
+\definecolor[hyphenation:1] [r=.8]
+\definecolor[hyphenation:2] [g=.8]
+\definecolor[hyphenation:3] [b=.8]
+\definecolor[hyphenation:4] [r=.4,g=.4]
+
+\definecolor[hyphenation:en] [hyphenation:1]
+\definecolor[hyphenation:de] [hyphenation:2]
+\definecolor[hyphenation:nl] [hyphenation:3]
+\definecolor[hyphenation:fr] [hyphenation:4]
+
+\stopmodule
+
+\continueifinputfile{s-languages-hyphenation.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+\def|#1|{-}
+
+ \startsubject{Normal text}
+ \input tufte
+ \stopsubject
+
+ \startsubject{Compare hyphenation points of \showcomparepatternslegend[en,de]}
+ \startcomparepatterns
+ \input tufte \quad (\showcomparepatternslegend)
+ \stopcomparepatterns
+ \stopsubject
+
+ \startsubject{Compare hyphenation points}
+ \startcomparepatterns[de,nl,en,fr]
+ \input tufte \quad (\showcomparepatternslegend)
+ \stopcomparepatterns
+ \stopsubject
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-sorting.lua b/tex/context/modules/mkiv/s-languages-sorting.lua
new file mode 100644
index 000000000..82a0827bb
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-sorting.lua
@@ -0,0 +1,118 @@
+if not modules then modules = { } end modules ['s-languages-system'] = {
+ version = 1.001,
+ comment = "companion to s-languages-system.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.sorting = moduledata.languages.sorting or { }
+
+local formatters = string.formatters
+local utfbyte, utfcharacters = utf.byte, utf.characters
+local sortedpairs = table.sortedpairs
+
+local definitions = sorters.definitions
+local constants = sorters.constants
+local replacementoffset = constants.replacementoffset
+
+local currentfont = font.current
+local fontchars = fonts.hashes.characters
+
+local c_darkblue = { "darkblue" }
+local c_darkred = { "darkred" }
+local f_chr = formatters["\\tttf%H"]
+
+local function chr(str,done)
+ if done then
+ context.space()
+ end
+ local c = fontchars[currentfont()]
+ for s in utfcharacters(str) do
+ local u = utfbyte(s)
+ if c[u] then
+ context(s)
+ elseif u > replacementoffset then
+ context.color(c_darkblue, f_chr(u))
+ else
+ context.color(c_darkred, f_chr(u))
+ end
+ end
+ return true
+end
+
+local function map(a,b,done)
+ if done then
+ context.space()
+ end
+ -- context.tttf()
+ chr(a)
+ context("=")
+ chr(b)
+ return true
+end
+
+local function nop()
+ -- context.tttf()
+ context("none")
+end
+
+local function key(data,field)
+ context.NC()
+ context(field)
+ context.NC()
+ context(data[field])
+ context.NC()
+ context.NR()
+end
+
+function moduledata.languages.sorting.showinstalled(tag)
+ if not tag or tag == "" or tag == interfaces.variables.all then
+ for tag, data in sortedpairs(definitions) do
+ moduledata.languages.sorting.showinstalled (tag)
+ end
+ else
+ sorters.update() -- syncs data
+ local data = definitions[tag]
+ if data then
+ context.starttabulate { "|lB|pl|" }
+ key(data,"language")
+ key(data,"parent")
+ key(data,"method")
+ context.NC()
+ context("replacements")
+ context.NC()
+ local replacements = data.replacements
+ if #replacements == 0 then
+ nop()
+ else
+ for i=1,#replacements do
+ local r = replacements[i]
+ map(r[1],r[2],i > 1)
+ end
+ end
+ context.NC()
+ context.NR()
+ context.NC()
+ context("order")
+ context.NC()
+ local orders = data.orders
+ for i=1,#orders do
+ chr(orders[i],i > 1)
+ end
+ context.NC()
+ context.NR()
+ context.NC()
+ context("entries")
+ context.NC()
+ local done = false
+ for k, e in sortedpairs(data.entries) do
+ done = map(k,e,done)
+ end
+ context.NC()
+ context.NR()
+ context.stoptabulate()
+ end
+ end
+end
diff --git a/tex/context/modules/mkiv/s-languages-sorting.mkiv b/tex/context/modules/mkiv/s-languages-sorting.mkiv
new file mode 100644
index 000000000..67acda6f9
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-sorting.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=s-languages-sorting, % s-lan-02.mkiv
+%D version=2010.09.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Language Sorting,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[languages-sorting]
+
+\registerctxluafile{s-languages-sorting}{}
+
+\installmodulecommandluasingle \showinstalledsorting {moduledata.languages.sorting.showinstalled}
+
+\stopmodule
+
+\continueifinputfile{s-languages-sorting.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showinstalledsorting
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-system.lua b/tex/context/modules/mkiv/s-languages-system.lua
new file mode 100644
index 000000000..3b422db9f
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-system.lua
@@ -0,0 +1,62 @@
+if not modules then modules = { } end modules ['s-languages-system'] = {
+ version = 1.001,
+ comment = "companion to s-languages-system.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.system = moduledata.languages.system or { }
+
+local NC, NR, HL = context.NC, context.NR, context.HL
+local sortedhash = table.sortedhash
+local registered = languages.registered
+local context = context
+local ctx_NC = context.NC
+local ctx_NR = context.NR
+local ctx_bold = context.bold
+
+function moduledata.languages.system.loadinstalled()
+ context.start()
+ for k, v in table.sortedhash(registered) do
+ context.language{ k }
+ end
+ context.stop()
+end
+
+function moduledata.languages.system.showinstalled()
+ --
+ context.starttabulate { "|l|r|l|l|p(7em)|r|p|" }
+ context.FL()
+ ctx_NC() ctx_bold("tag")
+ ctx_NC() ctx_bold("n")
+ ctx_NC() ctx_bold("parent")
+ ctx_NC() ctx_bold("file")
+ ctx_NC() ctx_bold("synonyms")
+ ctx_NC() ctx_bold("patterns")
+ ctx_NC() ctx_bold("characters")
+ ctx_NC() ctx_NR()
+ context.FL()
+ for k, v in sortedhash(registered) do
+ local parent = v.parent
+ local resources = v.resources
+ local patterns = resources and resources.patterns
+ ctx_NC() context(k)
+ ctx_NC() context(v.number)
+ ctx_NC() context(v.parent)
+ ctx_NC() context(v.patterns)
+ ctx_NC() for k, v in sortedhash(v.synonyms) do context("%s\\par",k) end
+ if patterns then
+ ctx_NC() context(patterns.n)
+ ctx_NC() context("% t",utf.split(patterns.characters))
+ else
+ ctx_NC()
+ ctx_NC()
+ end
+ ctx_NC() ctx_NR()
+ end
+ context.LL()
+ context.stoptabulate()
+ --
+end
diff --git a/tex/context/modules/mkiv/s-languages-system.mkiv b/tex/context/modules/mkiv/s-languages-system.mkiv
new file mode 100644
index 000000000..22991f264
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-system.mkiv
@@ -0,0 +1,32 @@
+%D \module
+%D [ file=s-languages-system, % moved from local s-lan-01
+%D version=2013.05.19,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Installed Languages,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[languages-system]
+
+\registerctxluafile{s-languages-system}{}
+
+\installmodulecommandluasingle \showinstalledlanguages {moduledata.languages.system.showinstalled}
+\installmodulecommandluasingle \loadinstalledlanguages {moduledata.languages.system.loadinstalled}
+
+\stopmodule
+
+\continueifinputfile{s-languages-system.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \loadinstalledlanguages
+ \showinstalledlanguages
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-languages-words.lua b/tex/context/modules/mkiv/s-languages-words.lua
new file mode 100644
index 000000000..ea7aee87b
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-words.lua
@@ -0,0 +1,32 @@
+if not modules then modules = { } end modules ['s-languages-words'] = {
+ version = 1.001,
+ comment = "companion to s-languages-words.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.languages = moduledata.languages or { }
+moduledata.languages.words = moduledata.languages.words or { }
+
+function moduledata.languages.words.showwords(specification)
+ local filename = specification.filename or file.addsuffix(tex.jobname,"words")
+ if lfs.isfile(filename) then
+ local w = dofile(filename)
+ if w then
+ -- table.print(w)
+ for cname, category in table.sortedpairs(w.categories) do
+ for lname, language in table.sortedpairs(category.languages) do
+ context.bold(string.format("category: %s, language: %s, total: %s, unique: %s:",
+ cname, lname, language.total or 0, language.unique or 0)
+ )
+ for word, n in table.sortedpairs(language.list) do
+ context(" %s (%s)",word,n)
+ end
+ context.par()
+ end
+ end
+ end
+ end
+end
+
diff --git a/tex/context/modules/mkiv/s-languages-words.mkiv b/tex/context/modules/mkiv/s-languages-words.mkiv
new file mode 100644
index 000000000..4e350bf34
--- /dev/null
+++ b/tex/context/modules/mkiv/s-languages-words.mkiv
@@ -0,0 +1,22 @@
+%D \module
+%D [ file=s-languages-words,
+%D version=2010.10.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Language Environment 3,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is used in the test suite.
+
+\startmodule[languages-words]
+
+\registerctxluafile{s-languages-words}{}
+
+\installmodulecommandluasingle \showwords {moduledata.languages.words.showwords}
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/s-map-10.mkiv b/tex/context/modules/mkiv/s-map-10.mkiv
new file mode 100644
index 000000000..c7541babc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-map-10.mkiv
@@ -0,0 +1,494 @@
+%D \module
+%D [file=s-map-10.mkiv,
+%D version=2012.06.06,
+%D title=\CONTEXT\ Style File,
+%D subtitle=\MAPS\ journal style,
+%D author={Hans Hagen, Taco Hoekwater and Siep Kroonenberg},
+%D date=\currentdate,
+%D copyright=NTG/MAPS]
+
+% This module implements the MAPS style for use with the Context
+% macro package. The original MAPS layout was designed and
+% implemented in LaTeX by Taco Hoekwater and Siep Kroonenberg.
+
+% - three layouts:
+% 1. two columns
+% 2. one column, with wide outer margins (option onecolumn)
+% 3. one column, with wide left margin (option asym)
+% - font sizes deviate from TeX's usual geometric progression
+% - use of sans-serif for headers and various details
+% - option realfonts uses Linux Libertine, Euler Math and Inconsolata.
+% This is used for final typesetting.
+% The default font setup, intended for authors, uses Computer
+% Modern Math instead of Euler Math (which is still in beta),
+% and LM Mono instead of Inconsolata.
+
+% A mode nosubsub defines only two levels of sectioning. If you
+% don't need more and use the two-column layout, then this option
+% will probably improve the looks of your paper.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newif\ifMapsInColumns
+\doifmode{asym}{\enablemode[onecolumn]} % implies onecolumn
+\doifnotmode{onecolumn}{\MapsInColumnstrue}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% fonts
+
+%%%%%%%%% first, font sizes
+\definebodyfontenvironment [7pt][% LaTeX: scriptsize
+ interlinespace=8pt,
+ big=8pt,
+ small=6pt%
+]
+
+\definebodyfontenvironment [8pt][% LaTeX: footnotesize
+ interlinespace=9pt,
+ big=9pt,
+ small=7pt,
+ x=6pt%
+]
+
+\definebodyfontenvironment [9pt][% LaTeX: small
+ interlinespace=10pt,
+ big=10pt,
+ small=8pt,%
+ x=7pt,%
+ script=6pt%
+]
+
+\definebodyfontenvironment [10pt][% LaTeX: normalsize
+ interlinespace=11pt,
+ big=11pt,
+ a=11pt,
+ small=9pt,%
+ x=8pt,%
+ script=7pt%
+]
+
+\definebodyfontenvironment [11pt][% LaTeX: large
+ interlinespace=11pt,
+ big=11pt,
+ small=10pt,%
+ x=9pt,%
+ script=8pt%
+]
+
+\definebodyfontenvironment [14pt][%
+ interlinespace=14pt,
+ big=18pt,
+ small=11pt,
+ x=10pt%
+]
+
+\definebodyfontenvironment [18pt][%
+ interlinespace=18pt,
+ big=24pt,
+ small=14pt,
+ x=10pt%
+]
+
+\definebodyfontenvironment [24pt][%
+ interlinespace=24pt,
+ big=24pt,
+ small=18pt,
+ x=11pt%
+]
+
+%%% font families
+
+\starttypescript [maps]
+\definetypeface [maps] [rm] [serif] [modern] [default] [rscale=0.95]
+\definetypeface [maps] [mm] [math] [modern] [latin-modern]
+\definetypeface [maps] [tt] [mono] [modern] [default] [rscale=0.90]
+\definetypeface [maps] [ss] [sans] [modern] [default] [rscale=0.95]
+\stoptypescript
+
+\startmode[realfonts]
+\usetypescriptfile[type-libertine]
+
+\usetypescriptfile[type-inconsolata]
+
+\starttypescript [maps]
+\definetypeface [maps] [rm] [serif] [libertine] [default]
+\definetypeface [maps] [mm] [math] [euler] [default] [rscale=0.9]
+\definetypeface [maps] [tt] [mono] [inconsolata] [default] [rscale=0.92]
+\definetypeface [maps] [ss] [sans] [modern] [default] [rscale=0.95]
+\stoptypescript
+\stopmode
+
+\setupbodyfont[maps,10pt,rm]
+
+% activate protruding
+\setupinterlinespace[line=11pt]
+
+\setupfontsynonym[handling=pure]
+
+\setupalign[hanging]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% additional general typographic details
+
+\setupindenting [yes,next,11pt] % indenting after enumerations etc.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% 3 versions of layout with matching headers
+
+\definepapersize
+ [maps]
+ [width=21cm,height=26.5cm]
+
+\setuppapersize
+ [maps][maps]
+
+\setuplayout[
+ [topspace=40pt,
+ height=688pt,
+ header=33pt,
+ margin=106pt,
+ leftmargindistance=11pt,
+ rightmargindistance=11pt]
+
+\setupblank[5.5pt]
+
+\setuppagenumbering [location=]
+
+\definetyping [widetyping]
+
+\setupheader [style=\ss]
+\setupfooter [style=\ss]
+
+\def\AuHead{\MapsRunningAuthor}
+\def\TiHead{\ifnum\pageno=\MapsPage \relax \MapsRunningAuthor \else \MapsRunningTitle\fi}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% sectioning
+
+\setupheads[sectionnumber=no, align=right]
+
+\def\hfonti{\ssbfa}
+\def\hfontii{\ssbf}
+\def\hfontiii{\rm\it}
+
+\doifelsemode{nosubsub}{%
+\setuphead [section][%
+ style=\hfontii,
+ before={\blank[line]},
+ after={}%
+]
+\setuphead [subsection][%
+ style=\hfontiii,
+ alternative=text,
+ distance=6pt,
+ before={\blank[halfline]}%
+]}{%
+\setuphead [section][%
+ style=\hfonti,
+ before={\blank[line]},
+ after={\blank[halfline]}%
+]
+\setuphead [subsection][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubsection][%
+ style=\hfontiii,
+ distance=6pt,
+ alternative=text,
+ before={\blank[halfline]}%
+]}
+
+\doifelsemode{nosubsub}{%
+\setuphead [subject][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubject][%
+ style=\hfontiii,
+ alternative=text,
+ before={\blank[halfline]}%
+]}{%
+\setuphead [subject][%
+ style=\hfonti,
+ before={\blank},
+ after={\blank[halfline]}%
+]
+\setuphead [subsubject][%
+ style=\hfontii,
+ before={\blank[halfline]},
+ after={}%
+]
+\setuphead [subsubsubject][%
+ style=\hfontiii,
+ alternative=text,
+ before={\blank[halfline]}%
+]}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% floats
+
+\setupfloats [location=center, before={\ss}]
+\setupcaptions [headstyle={\ssbf},style={\ssx},
+ suffix=.,distance=6pt,
+ inbetween={\blank[halfline]}]
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% various document elements
+
+\definesymbol [1][\getnamedglyphdirect{file:stmary10}{boxempty}]
+
+\setupitemize[1][packed]
+
+\setupitemize [each][%
+ indentnext=no,
+ align=right,
+ width=1em,
+ distance=0pt%
+]
+
+% an outer form of itemize that does not indent
+% the paragraph.
+
+\definecomplexorsimpleempty\startouteritemize
+\def\complexstartouteritemize[#1]{\begingroup
+ \startitemize[width=1sp,#1]
+ \let\doitem\item
+ \def\item{\doitem[]\hbox{}\kern12pt\rightskip=0pt}%
+}
+
+\def\stopouteritemize{\stopitemize\endgroup}
+
+
+\setupenumerations [indentnext=no]
+
+\setupdescriptions [indentnext=no]
+
+\unexpanded\def\smalltyping{%
+ \switchtobodyfont[tt]%
+ \parindent=0pt
+}
+
+% typing:
+% - prettyverbatim is NOT the default
+% - smaller size
+
+\unexpanded\def
+ \XeTeX{X\lower.5ex\hbox{\kern-.1em\mirror{E}}\kern-.1667em\TeX}
+
+\setuptyping [%
+ style={\smalltyping},
+ option=none,
+ indentnext=no%
+]
+
+\def\footnum#1{#1.}
+
+\setupnotation
+ [footnote]
+ [alternative=serried,
+ before=,
+ after=,
+ location=none,
+ width=\textwidth,
+ before={\blank},
+ numbercommand=,
+ command=\footnum,
+ distance=0.5em]
+
+\setuptabulate
+ [before=\blank,
+ inner=\ss,
+ after=\blank]
+
+\def\startIntroEntry#1%
+ {\startlinecorrection
+ \bgroup
+ \setupalign[right]
+ \setuptolerance[verytolerant]
+ \setupindenting[no]
+ \noindent
+ \switchtobodyfont[9pt]%
+ \setuplocalinterlinespace[line=10pt]%
+ %\hyphenpenalty10000
+ \parfillskip 0pt plus 1fill
+ \rightskip6pt plus 1fill
+ \ss
+ \bgroup\bf #1\par\egroup
+ \ignorespaces }
+
+\def\stopIntroEntry
+ {\par\egroup \stoplinecorrection
+ \blank[line] }
+
+\def\defineIntroEntry[#1][#2][#3]%
+ {\setvalue{start#1}{\startIntroEntry{#2}}%
+ \setvalue {stop#1}{\stopIntroEntry#3}}
+
+\defineIntroEntry[Keywords][Keywords][]
+\defineIntroEntry[Abstract][Abstract][]
+
+% article parameters (other fields and defaults)
+\def\MapsBibData[#1]%
+ {\getparameters [Maps]
+ [SubTitle=,
+ RunningAuthor=,
+ RunningTitle=,
+ Email=,
+ Address=,
+ Page=1,
+ Title=,
+ Author=,
+ Period=,
+ Number=,
+ Year=,
+ #1]%
+ \doifnothing{\MapsPeriod}{%
+ \ifnum \normalmonth<6 \gdef\MapsPeriod{VOORJAAR}\else \gdef\MapsPeriod{NAJAAR}\fi}
+ \doifelseinstring{oorjaar}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}%
+ \doifelseinstring{pring}{\MapsPeriod}{\gdef\MapsPeriod{VOORJAAR}}{}%
+ \doifelseinstring{ajaar}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}%
+ \doifelseinstring{utumn}{\MapsPeriod}{\gdef\MapsPeriod{NAJAAR}}{}%
+ \doifnothing{\MapsYear}{\gdef\MapsYear{\the\year}}%
+ \doifnothing{\MapsNumber}{%
+ \ifnum \normalmonth<6
+ \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2\relax}%
+ \else
+ \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2+1\relax}%
+ \fi }%
+ \doifnothing\MapsRunningAuthor
+ {\global\let\MapsRunningAuthor\MapsAuthor}%
+ \doifnothing\MapsRunningTitle
+ {\global\let\MapsRunningTitle\MapsTitle}}%
+
+\def\dostartArticle[#1]{%
+ \MapsBibData[#1]
+ \pageno=\MapsPage
+ \setupuserpagenumber[start=\MapsPage]
+ \startbaselinecorrection
+ \bgroup
+ \hsize = 457pt
+ \let\\\crlf
+ \blank[35pt,force]
+ \switchtobodyfont[24pt]
+ \setupalign[right]
+ {\noindent\bf\MapsTitle\par}
+ \ifx\MapsSubTitle\empty
+ \blank[30pt]
+ \else
+ \bgroup
+ \blank[12pt]
+ \switchtobodyfont[18pt]\noindent \it
+ \advance \rightskip 0pt plus 2em
+ \MapsSubTitle\par
+ \egroup
+ \blank[30pt]
+ \fi
+ \egroup
+ \setupalign[width]
+ \switchtobodyfont[rm,10pt]
+ \stopbaselinecorrection
+ \ifMapsInColumns
+ \startcolumns\hyphenpenalty1000
+ \else
+ \clubpenalty10000
+ \widowpenalty10000
+ \fi
+}
+
+\def\startArticle{\dosingleempty\dostartArticle}
+
+\def\signArticle{%
+ \blank\let\\\crlf
+ \noindent\switchtobodyfont[ss,9pt]%
+ \MapsAuthor
+ \doifsomething{\MapsAddress}{\\\MapsAddress}%
+ \doifsomething{\MapsEmail}{\\\MapsEmail}%
+ \switchtobodyfont[10pt]%
+ \def\signArticle{}%
+}
+
+\def\stopArticle{%
+ \par\signArticle
+ \ifMapsInColumns \stopcolumns \fi
+ \page
+}
+
+\installpagebreakmethod{last}{}
+
+%%% `logos' %%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\unexpanded\def\LaTeX % requested by erik frambach
+ {{\setbox\scratchbox\hbox{L}%
+ \scratchdimen\ht\scratchbox
+ \setbox\scratchbox\hbox{\switchtobodyfont[script]A}%
+ L\kern-.55\wd\scratchbox
+ \raise\scratchdimen\hbox{\lower\ht\scratchbox\copy\scratchbox}%
+ \kern-.2\wd\scratchbox\TeX}}
+
+
+\def\CONTEXT{Con{\TeX}t}
+\def\ConTeXt{Con{\TeX}t}
+\def\METAFONT{Metafont}
+\def\METAPOST{MetaPost}
+\def\POSTSCRIPT{PostScript}
+
+\def\acro#1{{\switchtobodyfont[9pt]#1}}
+
+
+%%%%%%%%%%%
+
+\doifelsemode{onecolumn}{%
+ \setuplayout[width=340pt]
+ \doifelsemode{asym}{% one col, asymmetric
+ \setuplayout[backspace=187.3pt]%
+ \setuptyping [widetyping][oddmargin=-117pt]
+ \setuppagenumbering [alternative={singlesided,doublesided}]
+ \setupheadertexts
+ [{\hbox{}\hskip-117pt\TiHead}]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}]
+ [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+ }{% one col, symmetric
+ \setuplayout[backspace=70.3pt]
+ \setuppagenumbering [alternative=doublesided]
+ \setuptyping[blank=halfline]
+ \setupheadertexts
+ [\TiHead]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-147pt\hbox{}}]
+ [{\hbox{}\hskip-147pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+}}{% two col
+ \setuplayout[width=457pt]
+ \setupcolumns[n=2,tolerance=verytolerant,distance=11pt]
+ \setuplayout[backspace=70.3pt,grid=yes]
+ \setuppagenumbering [alternative=doublesided]
+ \setuptyping[blank=halfline]
+ \setupheadertexts
+ [\TiHead]
+ [{\cap{\MapsPeriod\ \MapsYear}\quad\bf \pagenumber\hskip-30pt\hbox{}}]
+ [{\hbox{}\hskip-30pt{\bf \pagenumber}\quad \cap {maps\ \MapsNumber}}]
+ [\AuHead]
+ \setupfootertexts
+}
+
+\def\fulltextwidth{457pt}
+
+\def\startdescription
+ {\blank
+ \bgroup
+ \def\sym##1{\par\noindent\hbox{\bf\kern -16pt ##1}\hskip 12pt}
+ \startnarrower[left]
+ }
+\def\stopdescription
+ {\par \stopnarrower \egroup \blank \noindentation }
+
+\frenchspacing
+\setuptolerance[tolerant]
+
+\endinput
diff --git a/tex/context/modules/mkiv/s-math-characters.lua b/tex/context/modules/mkiv/s-math-characters.lua
new file mode 100644
index 000000000..8ff3a8660
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-characters.lua
@@ -0,0 +1,242 @@
+if not modules then modules = { } end modules['s-math-characters'] = {
+ version = 1.001,
+ comment = "companion to s-math-characters.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is one of the oldest cld files but I'm not going to clean it up.
+
+moduledata.math = moduledata.math or { }
+moduledata.math.characters = moduledata.math.characters or { }
+
+local concat = table.concat
+local lower = string.lower
+local utfchar = utf.char
+local round = math.round
+
+local fontdata = fonts.hashes.identifiers
+local chardata = characters.data
+local blocks = characters.blocks
+
+local no_description = "no description, private to font"
+
+local limited = true
+local fillinthegaps = true
+local upperlimit = 0x0007F
+local upperlimit = 0xF0000
+
+local f_unicode = string.formatters["%U"]
+local f_slot = string.formatters["%s/%0X"]
+
+function moduledata.math.characters.showlist(specification)
+ specification = interfaces.checkedspecification(specification)
+ local id = specification.number -- or specification.id
+ local list = specification.list
+ local showvirtual = specification.virtual == "all"
+ local check = specification.check == "yes"
+ if not id then
+ id = font.current()
+ end
+ if list == "" then
+ list = nil
+ end
+ local tfmdata = fontdata[id]
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ local resources = tfmdata.resources
+ local lookuptypes = resources.lookuptypes
+ local virtual = tfmdata.properties.virtualized
+ local names = { }
+ local gaps = mathematics.gaps
+ local sorted = { }
+ if type(list) == "string" then
+ sorted = utilities.parsers.settings_to_array(list)
+ elseif type(list) == "table" then
+ sorted = list
+ elseif fillinthegaps then
+ sorted = table.keys(characters)
+ for k, v in next, gaps do
+ if characters[v] then
+ sorted[#sorted+1] = k
+ end
+ end
+ table.sort(sorted)
+ else
+ sorted = table.sortedkeys(characters)
+ end
+ if virtual then
+ for k, v in ipairs(tfmdata.fonts) do
+ local id = v.id
+ local name = fontdata[id].properties.name
+ names[k] = (name and file.basename(name)) or id
+ end
+ end
+ if check then
+ for k, v in table.sortedhash(blocks) do
+ if v.math then
+ local first = v.first
+ local last = v.last
+ local f, l = 0, 0
+ if first and last then
+ for unicode=first,last do
+ local code = gaps[unicode] or unicode
+ local char = characters[code]
+ if char and not (char.commands and not showvirtual) then
+ f = unicode
+ break
+ end
+ end
+ for unicode=last,first,-1 do
+ local code = gaps[unicode] or unicode
+ local char = characters[code]
+ if char and not (char.commands and not showvirtual) then
+ l = unicode
+ break
+ end
+ end
+ context.showmathcharacterssetrange(k,f,l)
+ end
+ end
+ end
+ else
+ context.showmathcharactersstart()
+ for _, unicode in next, sorted do
+ if not limited or unicode < upperlimit then
+ local code = gaps[unicode] or unicode
+ local char = characters[code]
+ local desc = descriptions[code]
+ local info = chardata[code]
+ if char then
+ local commands = char.commands
+ if commands and not showvirtual then
+ -- skip
+ else
+ local next_sizes = char.next
+ local v_variants = char.vert_variants
+ local h_variants = char.horiz_variants
+ local slookups = desc and desc.slookups
+ local mlookups = desc and desc.mlookups
+ local mathclass = info.mathclass
+ local mathspec = info.mathspec
+ local mathsymbol = info.mathsymbol
+ local description = info.description or no_description
+ context.showmathcharactersstartentry()
+ context.showmathcharactersreference(f_unicode(unicode))
+ context.showmathcharactersentryhexdectit(f_unicode(code),code,lower(description))
+ context.showmathcharactersentrywdhtdpic(round(char.width or 0),round(char.height or 0),round(char.depth or 0),round(char.italic or 0))
+ if virtual and commands then
+ local t = { }
+ for i=1,#commands do
+ local ci = commands[i]
+ if ci[1] == "slot" then
+ local fnt, idx = ci[2], ci[3]
+ t[#t+1] = f_slot(names[fnt] or fnt,idx)
+ end
+ end
+ if #t > 0 then
+ context.showmathcharactersentryresource(concat(t,", "))
+ end
+ end
+ if mathclass or mathspec then
+ context.showmathcharactersstartentryclassspec()
+ if mathclass then
+ context.showmathcharactersentryclassname(mathclass,info.mathname or "no name")
+ end
+ if mathspec then
+ for i=1,#mathspec do
+ local mi = mathspec[i]
+ context.showmathcharactersentryclassname(mi.class,mi.name or "no name")
+ end
+ end
+ context.showmathcharactersstopentryclassspec()
+ end
+ if mathsymbol then
+ context.showmathcharactersentrysymbol(f_unicode(mathsymbol),mathsymbol)
+ end
+ if next_sizes then
+ local n, done = 0, { }
+ context.showmathcharactersstartnext()
+ while next_sizes do
+ n = n + 1
+ if done[next_sizes] then
+ context.showmathcharactersnextcycle(n)
+ break
+ else
+ done[next_sizes] = true
+ context.showmathcharactersnextentry(n,f_unicode(next_sizes),next_sizes)
+ next_sizes = characters[next_sizes]
+ v_variants = next_sizes.vert_variants or v_variants
+ h_variants = next_sizes.horiz_variants or h_variants
+ if next_sizes then
+ next_sizes = next_sizes.next
+ end
+ end
+ end
+ context.showmathcharactersstopnext()
+ if h_variants or v_variants then
+ context.showmathcharactersbetweennextandvariants()
+ end
+ end
+ if h_variants then
+ context.showmathcharactersstarthvariants()
+ for i=1,#h_variants do -- we might go top-down in the original
+ local vi = h_variants[i]
+ context.showmathcharactershvariantsentry(i,f_unicode(vi.glyph),vi.glyph)
+ end
+ context.showmathcharactersstophvariants()
+ elseif v_variants then
+ context.showmathcharactersstartvvariants()
+ for i=1,#v_variants do
+ local vi = v_variants[#v_variants-i+1]
+ context.showmathcharactersvvariantsentry(i,f_unicode(vi.glyph),vi.glyph)
+ end
+ context.showmathcharactersstopvvariants()
+ end
+ if slookups or mlookups then
+ local variants = { }
+ if slookups then
+ for lookupname, lookupdata in next, slookups do
+ local lookuptype = lookuptypes[lookupname]
+ if lookuptype == "substitution" then
+ variants[lookupdata] = "sub"
+ elseif lookuptype == "alternate" then
+ for i=1,#lookupdata do
+ variants[lookupdata[i]] = "alt"
+ end
+ end
+ end
+ end
+ if mlookups then
+ for lookupname, lookuplist in next, mlookups do
+ local lookuptype = lookuptypes[lookupname]
+ for i=1,#lookuplist do
+ local lookupdata = lookuplist[i]
+ local lookuptype = lookuptypes[lookupname]
+ if lookuptype == "substitution" then
+ variants[lookupdata] = "sub"
+ elseif lookuptype == "alternate" then
+ for i=1,#lookupdata do
+ variants[lookupdata[i]] = "alt"
+ end
+ end
+ end
+ end
+ end
+ context.showmathcharactersstartlookupvariants()
+ local i = 0
+ for variant, lookuptype in table.sortedpairs(variants) do
+ i = i + 1
+ context.showmathcharacterslookupvariant(i,f_unicode(variant),variant,lookuptype)
+ end
+ context.showmathcharactersstoplookupvariants()
+ end
+ context.showmathcharactersstopentry()
+ end
+ end
+ end
+ end
+ context.showmathcharactersstop()
+ end
+end
diff --git a/tex/context/modules/mkiv/s-math-characters.mkiv b/tex/context/modules/mkiv/s-math-characters.mkiv
new file mode 100644
index 000000000..3b273cb6c
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-characters.mkiv
@@ -0,0 +1,193 @@
+%D \module
+%D [ file=s-math-characters.mkiv, % was: s-fnt-25 and later s-mat-10
+%D version=2009.01.25,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Math Glyph Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[math-characters]
+
+\registerctxluafile{s-math-characters}{}
+
+% context --jit --global --bodyfont=cambria --result=math-characters-cambria s-math-characters.mkiv
+% context --jit --global --bodyfont=modern --result=math-characters-modern s-math-characters.mkiv
+
+\startsetups s-math-characters:reset
+
+ \let\showmathcharactersstart \relax
+ \let\showmathcharactersstop \relax
+ \let\showmathcharactersreference \gobbleoneargument
+ \let\showmathcharactersstartentry \relax
+ \let\showmathcharactersstopentry \relax
+ \let\showmathcharactersentryhexdectit \gobblethreearguments
+ \let\showmathcharactersentrywdhtdpic \gobblefourarguments
+ \let\showmathcharactersentryresource \gobbleoneargument
+ \let\showmathcharactersstartnext \relax
+ \let\showmathcharactersnextentry \gobblethreearguments
+ \let\showmathcharactersnextcycle \gobbleonearguments
+ \let\showmathcharactersstopnext \relax
+ \let\showmathcharactersstarthvariants \relax
+ \let\showmathcharactershvariantsentry \gobblethreearguments
+ \let\showmathcharactersstophvariants \relax
+ \let\showmathcharactersstartvvariants \showmathcharactersstarthvariants
+ \let\showmathcharactersvvariantsentry \showmathcharactershvariantsentry
+ \let\showmathcharactersstopvvariants \showmathcharactersstophvariants
+ \let\showmathcharactersbetweennextandvariants\relax
+ \let\showmathcharactersstartentryclassspec \relax
+ \let\showmathcharactersstopentryclassspec \relax
+ \let\showmathcharactersentryclassname \gobbletwoarguments
+ \let\showmathcharactersentrysymbol \gobbletwoarguments
+ \let\showmathcharactersstartlookupvariants \relax
+ \let\showmathcharacterslookupvariant \gobblefourarguments
+ \let\showmathcharactersstoplookupvariants \relax
+ \let\showmathcharacterssetrange \gobblethreearguments
+
+\stopsetups
+
+\directsetup{s-math-characters:reset}
+
+\startsetups s-math-characters:default
+
+ \directsetup{s-math-characters:reset}
+
+ \unexpanded\def\showmathcharactersstartentry {\blank\begingroup\raggedright}
+ \unexpanded\def\showmathcharactersstopentry {\endgroup\blank}
+
+ \def\showmathcharactersentryhexdectit##1##2##3%
+ {##1:\space{\char##2}\space\ruledhbox{\char##2}\space##3\par
+ \advance\leftskip\emwidth\relax}
+
+ \def\showmathcharactersentrywdhtdpic##1##2##3##4%
+ {width:\space##1,\space height:\space##2,\space depth:\space##3,\space italic:\space##4\par}
+
+ \def\showmathcharactersentryresource##1%
+ {virtual:\space##1\par}
+
+ \def\showmathcharactersstartnext
+ {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth
+ next:\space}
+
+ \def\showmathcharactersnextentry##1##2##3%
+ {\ifnum##1>\plusone \space=>\space\fi##2~\ruledhbox{\char##3}}
+
+ \def\showmathcharactersnextcycle##1%
+ {\ifnum##1>\plusone \space=>\space\fi cycle}
+
+ \def\showmathcharactersstopnext
+ {\par\endgroup}
+
+ \def\showmathcharactersstarthvariants
+ {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth
+ variants:\space}
+
+ \def\showmathcharactershvariantsentry##1##2##3%
+ {\ifnum##1>\plusone \space=>\space\fi##2~\ruledhbox{\char##3}}
+
+ \def\showmathcharactersstophvariants
+ {\par\endgroup}
+
+ \let\showmathcharactersstartvvariants\showmathcharactersstarthvariants
+ \let\showmathcharactersvvariantsentry\showmathcharactershvariantsentry
+ \let\showmathcharactersstopvvariants \showmathcharactersstophvariants
+
+ \def\showmathcharactersbetweennextandvariants
+ {}% \space=>\space}
+
+ \def\showmathcharactersentryclassname##1##2%
+ {mathclass:\space##1,\space mathname:\space##2\par}
+
+ \def\showmathcharactersentrysymbol##1##2%
+ {mathsymbol:\space##1~\ruledhbox{\char##2}\par}
+
+ \def\showmathcharactersstartlookupvariants
+ {\par\begingroup\hangindent\emwidth\hangafter-\plushundred\hskip-\emwidth
+ lookupvariants:\space}
+
+ \def\showmathcharacterslookupvariant##1##2##3##4%
+ {\ifnum##1>\plusone,\space\fi##2:~{\char##3}\space(##4)}
+
+ \def\showmathcharactersstoplookupvariants
+ {\par\endgroup}
+
+\stopsetups
+
+\unprotect
+
+\unexpanded\def\enableshowmathfontvirtual
+ {\ctxlua{fonts.constructors.autocleanup=false}}
+
+\unexpanded\def\showmathfontcharacters
+ {\dosingleempty\module_math_characters_show}
+
+\def\module_math_characters_show[#1]%
+ {\begingroup
+ \getdummyparameters
+ [\c!bodyfont=,
+ \c!list=,
+ \c!check=,
+ \c!alternative=default,
+ \c!option=\v!all,
+ #1]%
+ \directsetup{s-math-characters:\dummyparameter\c!alternative}%
+ \doifelsenothing{\dummyparameter\c!bodyfont}
+ {\definedfont[MathRoman*math-text]}
+ {\definedfont[\dummyparameter\c!bodyfont]}%
+ \dontcomplain
+ \ctxlua{moduledata.math.characters.showlist {
+ number = false,
+ check = "\dummyparameter\c!check",
+ list = "\dummyparameter\c!list",
+ option = "\dummyparameter\c!option",
+ }}%
+ \endgroup}
+
+\protect
+
+\stopmodule
+
+\continueifinputfile{s-math-characters.mkiv}
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ topspace=15mm,
+ backspace=15mm,
+ bottomspace=15mm,
+ header=1cm,
+ headerdistance=0.5cm,
+ footer=0pt]
+
+\starttext
+
+ \doifelse {\getdocumentargument{bodyfont}} {} {
+
+ \setupbodyfont[cambria, 12pt]
+ % \setupbodyfont[modern, 12pt]
+ % \setupbodyfont[lmvirtual, 12pt]
+ % \setupbodyfont[pxvirtual, 12pt]
+ % \setupbodyfont[txvirtual, 12pt]
+ % \setupbodyfont[palatino, 10pt]
+ % \setupbodyfont[mathtimes, 12pt]
+ % \setupbodyfont[stix, 12pt]
+ % \setupbodyfont[xits, 12pt]
+ % \setupbodyfont[lucida, 12pt]
+ % \setupbodyfont[lucidanova,12pt]
+ % \setupbodyfont[pagella, 12pt]
+ % \setupbodyfont[bonum, 12pt]
+
+ } {
+
+ \normalexpanded{\setupbodyfont[\getdocumentargument{bodyfont},12pt]}
+
+ }
+
+ \showmathfontcharacters
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/s-math-coverage.lua b/tex/context/modules/mkiv/s-math-coverage.lua
new file mode 100644
index 000000000..3c6080dc3
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-coverage.lua
@@ -0,0 +1,197 @@
+if not modules then modules = { } end modules ['s-math-coverage'] = {
+ version = 1.001,
+ comment = "companion to s-math-coverage.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local utfchar, utfbyte = utf.char, utf.byte
+local formatters, lower = string.formatters, string.lower
+local concat = table.concat
+local sortedhash = table.sortedhash
+
+moduledata.math = moduledata.math or { }
+moduledata.math.coverage = moduledata.math.coverage or { }
+
+local context = context
+
+local ctx_NC = context.NC
+local ctx_NR = context.NR
+local ctx_HL = context.HL
+
+local ctx_startmixedcolumns = context.startmixedcolumns
+local ctx_stopmixedcolumns = context.stopmixedcolumns
+local ctx_setupalign = context.setupalign
+local ctx_starttabulate = context.starttabulate
+local ctx_stoptabulate = context.stoptabulate
+local ctx_rawmathematics = context.formatted.rawmathematics
+local ctx_mathematics = context.formatted.mathematics
+local ctx_startimath = context.startimath
+local ctx_stopimath = context.stopimath
+local ctx_setmathattribute = context.setmathattribute
+local ctx_underbar = context.underbar
+local ctx_getglyph = context.getglyph
+
+local styles = mathematics.styles
+local alternatives = mathematics.alternatives
+local charactersets = mathematics.charactersets
+
+local getboth = mathematics.getboth
+local remapalphabets = mathematics.remapalphabets
+
+local chardata = characters.data
+local superscripts = characters.superscripts
+local subscripts = characters.subscripts
+
+context.writestatus("math coverage","underline: not remapped")
+
+function moduledata.math.coverage.showalphabets()
+ ctx_starttabulate { "|lT|l|Tl|" }
+ for i=1,#styles do
+ local style = styles[i]
+ for i=1,#alternatives do
+ local alternative = alternatives[i]
+ for _, alphabet in sortedhash(charactersets) do
+ ctx_NC()
+ if i == 1 then
+ context("%s %s",style,alternative)
+ end
+ ctx_NC()
+ ctx_startimath()
+ ctx_setmathattribute(style,alternative)
+ for i=1,#alphabet do
+ local letter = alphabet[i]
+ local id = getboth(style,alternative)
+ local unicode = remapalphabets(letter,id)
+ if not unicode then
+ ctx_underbar(utfchar(letter))
+ elseif unicode == letter then
+ context(utfchar(unicode))
+ else
+ context(utfchar(unicode))
+ end
+ end
+ ctx_stopimath()
+ ctx_NC()
+ local first = alphabet[1]
+ local last = alphabet[#alphabet]
+ local id = getboth(style,alternative)
+ local f_unicode = remapalphabets(first,id) or utfbyte(first)
+ local l_unicode = remapalphabets(last,id) or utfbyte(last)
+ context("%05X - %05X",f_unicode,l_unicode)
+ ctx_NC()
+ ctx_NR()
+ end
+ end
+ end
+ ctx_stoptabulate()
+end
+
+function moduledata.math.coverage.showcharacters()
+ ctx_startmixedcolumns { balance = "yes" }
+ ctx_setupalign { "nothyphenated" }
+ ctx_starttabulate { "|T|i2|Tpl|" }
+ for u, d in sortedhash(chardata) do
+ local mathclass = d.mathclass
+ local mathspec = d.mathspec
+ if mathclass or mathspec then
+ ctx_NC()
+ context("%05X",u)
+ ctx_NC()
+ ctx_getglyph("MathRoman",u)
+ ctx_NC()
+ if mathspec then
+ local t = { }
+ for i=1,#mathspec do
+ t[mathspec[i].class] = true
+ end
+ t = table.sortedkeys(t)
+ context("% t",t)
+ else
+ context(mathclass)
+ end
+ ctx_NC()
+ ctx_NR()
+ end
+ end
+ ctx_stoptabulate()
+ ctx_stopmixedcolumns()
+end
+
+-- This is a somewhat tricky table as we need to bypass the math machinery.
+
+function moduledata.math.coverage.showscripts()
+ ctx_starttabulate { "|cT|c|cT|c|c|c|l|" }
+ for k, v in sortedhash(table.merged(superscripts,subscripts)) do
+ local ck = utfchar(k)
+ local cv = utfchar(v)
+ local ss = superscripts[k] and "^" or "_"
+ ctx_NC() context("%05X",k)
+ ctx_NC() context(ck)
+ ctx_NC() context("%05X",v)
+ ctx_NC() context(cv)
+ ctx_NC() ctx_rawmathematics("x%s = x%s%s",ck,ss,cv)
+ ctx_NC() ctx_mathematics("x%s = x%s%s",ck,ss,cv)
+ ctx_NC() context(lower(chardata[k].description))
+ ctx_NC() ctx_NR()
+ end
+ ctx_stoptabulate()
+end
+
+-- Handy too.
+
+function moduledata.math.coverage.showbold()
+ ctx_starttabulate { "|lT|cm|lT|cm|lT|" }
+ for k, v in sortedhash(mathematics.boldmap) do
+ ctx_NC() context("%U",k)
+ ctx_NC() context("%c",k)
+ ctx_NC() context("%U",v)
+ ctx_NC() context("%c",v)
+ ctx_NC() context(chardata[k].description)
+ ctx_NC() ctx_NR()
+ end
+ ctx_stoptabulate()
+end
+
+-- function moduledata.math.coverage.showentities()
+-- ctx_startmixedcolumns { balance = "yes" }
+-- ctx_starttabulate { "|Tl|c|Tl|" }
+-- for k, v in sortedhash(characters.entities) do
+-- local b = utf.byte(v)
+-- local d = chardata[b]
+-- local m = d.mathname
+-- local c = d.contextname
+-- local s = ((m and "\\"..m) or (c and "\\".. c) or v) .. "{}{}{}"
+-- ctx_NC()
+-- context("%U",b)
+-- ctx_NC()
+-- ctx_mathematics(s)
+-- ctx_NC()
+-- context(k)
+-- ctx_NC()
+-- ctx_NR()
+-- end
+-- ctx_stoptabulate()
+-- ctx_stopmixedcolumns()
+-- end
+
+function moduledata.math.coverage.showentities()
+ ctx_startmixedcolumns { balance = "yes" }
+ ctx_starttabulate { "|T||T|T|" }
+ for k, v in sortedhash(characters.entities) do
+ local d = chardata[v]
+ if d then
+ local m = d.mathclass or d.mathspec
+ local u = d.unicodeslot
+ ctx_NC() context(m and "m" or "t")
+ ctx_NC() ctx_getglyph("MathRoman",u)
+ ctx_NC() context("%05X",u)
+ ctx_NC() context(k)
+ ctx_NC() ctx_NR()
+ end
+ end
+ ctx_stoptabulate()
+ ctx_stopmixedcolumns()
+end
+
diff --git a/tex/context/modules/mkiv/s-math-coverage.mkiv b/tex/context/modules/mkiv/s-math-coverage.mkiv
new file mode 100644
index 000000000..e318c9eff
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-coverage.mkiv
@@ -0,0 +1,38 @@
+%D \module
+%D [ file=s-math-coverage, % s-fnt-33, s-fnt-32
+%D version=2011.05.10, % and older
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Math Coverage,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[math-coverage]
+
+\registerctxluafile{s-math-coverage}{}
+
+\installmodulecommandluasingle \showmathalphabets {moduledata.math.coverage.showalphabets}
+\installmodulecommandluasingle \showmathcharacters{moduledata.math.coverage.showcharacters}
+\installmodulecommandluasingle \showmathscripts {moduledata.math.coverage.showscripts}
+\installmodulecommandluasingle \showmathbold {moduledata.math.coverage.showbold}
+\installmodulecommandluasingle \showmathentities {moduledata.math.coverage.showentities}
+
+\stopmodule
+
+\continueifinputfile{s-math-coverage.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showmathalphabets \page
+ \showmathcharacters \page
+ \showmathscripts \page
+ \showmathbold \page
+ \showmathentities \page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-math-extensibles.mkiv b/tex/context/modules/mkiv/s-math-extensibles.mkiv
new file mode 100644
index 000000000..f9ff8547a
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-extensibles.mkiv
@@ -0,0 +1,145 @@
+%D \module
+%D [ file=s-math-extensibles.mkiv,
+%D version=2013.02.03,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Math Stackers Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This module provides a macro that will typeset a table of (horizontal)
+%D extensibles including some tracing. You can set up the \type {demo}
+%D stacker category to tweak things.
+%D
+%D \starttyping
+%D \showmathextensibles[alternative=a|b]
+%D \stoptyping
+
+\startmodule[math-extensibles]
+
+\unprotect
+
+\definemathstackers
+ [demo]
+ [math]
+ [\c!offset=\v!max]
+
+\installcorenamespace{modulemathextensibles}
+\installcorenamespace{modulemathextensiblesalternative}
+
+\installdirectsetuphandler \??modulemathextensibles {modulemathextensibles}
+
+\setupmodulemathextensibles
+ [\c!alternative=\v!a]
+
+\unexpanded\def\showmathextensibles
+ {\dosingleempty\module_math_extensibles_show_all}
+
+\def\module_math_extensibles_show_all[#1]%
+ {\begingroup
+ \setupcurrentmodulemathextensibles[#1]%
+ \expandnamespacevalue\??modulemathextensiblesalternative\c!alternative\v!a
+ \endgroup}
+
+\def\modulemathextensiblesalternativea#1#2#3%
+ {\NC U+#1
+ \NC \filledhboxm{\math{\char"#1}}
+ \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{bottom}}}
+ \NC \hbox{\math{\mathextensible[demo]{"#1}{}{bottom}}}
+ \NC \hbox{\math{\mathextensible[demo]{"#1}{top}{}}}
+ \NC \nohyphens \veryraggedright #2
+ \NC\NR}
+
+\setvalue{\??modulemathextensiblesalternative\v!a}%
+ {\enabletrackers[math.stackers.texts]
+ \starttabulate[|Tl|l|l|l|l|Tp|]
+ \ctxlua { moduledata.math.extensibles.show {
+ command = "modulemathextensiblesalternativea",
+ } }
+ \stoptabulate
+ \disabletrackers[math.stackers.texts]}
+
+\def\modulemathextensiblesalternativeb#1#2#3%
+ {\NC U+#1
+ \NC \math{\char"#1}
+ \NC \nohyphens \veryraggedright #3
+ \NC \NR}
+
+\setvalue{\??modulemathextensiblesalternative\v!b}%
+ {\enabletrackers[math.stackers.texts]
+ \starttabulate[|Tl|l|Tp|]
+ \ctxlua { moduledata.math.extensibles.show {
+ command = "modulemathextensiblesalternativeb",
+ sparse = true,
+ } }
+ \stoptabulate
+ \disabletrackers[math.stackers.texts]}
+
+\startluacode
+ moduledata.math = moduledata.math or { }
+ moduledata.math.extensibles = moduledata.math.extensibles or { }
+
+ function moduledata.math.extensibles.show(settings)
+ local command = settings.command
+ local sparse = settings.sparse
+ for k, v in table.sortedhash(characters.data) do
+ local mathextensible = v.mathextensible
+ if mathextensible == "r" or mathextensible == "l" or mathextensible == "h" then
+ local names = { }
+ local mathname = v.mathname
+ if mathname then
+ names[#names+1] = v.mathclass .. ":" .. mathname
+ end
+ local mathspec = v.mathspec
+ if mathspec then
+ for i=1,#mathspec do
+ local v = mathspec[i]
+ names[#names+1] = v.class .. ":" .. v.name
+ end
+ end
+ local mathfiller = v.mathfiller
+ if mathfiller then
+ names[#names+1] = "filler:" .. mathfiller
+ end
+ if not sparse or #names > 0 then
+ context[command](string.format("%04X",k),v.description,table.concat(names," "))
+ end
+ end
+ end
+ end
+\stopluacode
+
+\protect
+
+\stopmodule
+
+\continueifinputfile{s-math-extensibles.mkiv}
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ footer=0cm,
+ backspace=1.5cm,
+ topspace=1.5cm]
+
+\setuphead[chapter][style=\bfc]
+\setuphead[section][style=\bfa]
+
+\starttext
+
+ \dowith {a,b} {
+
+ \page \title {Latin Modern} \showmathextensibles[alternative=#1]
+ \page \setupbodyfont[pagella] \title {Pagella} \showmathextensibles[alternative=#1]
+ \page \setupbodyfont[termes] \title {Termes} \showmathextensibles[alternative=#1]
+ \page \setupbodyfont[dejavu] \title {Xits} \showmathextensibles[alternative=#1]
+ \page \setupbodyfont[cambria] \title {Cambria} \showmathextensibles[alternative=#1]
+ \page \setupbodyfont[lucidaot] \title {Lucida} \showmathextensibles[alternative=#1]
+
+ }
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-math-parameters.lua b/tex/context/modules/mkiv/s-math-parameters.lua
new file mode 100644
index 000000000..8e8c15a2d
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-parameters.lua
@@ -0,0 +1,135 @@
+if not modules then modules = { } end modules ['s-math-coverage'] = {
+ version = 1.001,
+ comment = "companion to s-math-coverage.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.math = moduledata.math or { }
+moduledata.math.parameters = moduledata.math.parameters or { }
+
+local tables = utilities.tables.definedtable("math","tracing","spacing","tables")
+
+tables.styleaxis = {
+ "ord", "op", "bin", "rel", "open", "close", "punct", "inner",
+}
+
+tables.parameters = {
+ "quad", "axis", "operatorsize",
+ "overbarkern", "overbarrule", "overbarvgap",
+ "underbarkern", "underbarrule", "underbarvgap",
+ "radicalkern", "radicalrule", "radicalvgap",
+ "radicaldegreebefore", "radicaldegreeafter", "radicaldegreeraise",
+ "stackvgap", "stacknumup", "stackdenomdown",
+ "fractionrule", "fractionnumvgap", "fractionnumup",
+ "fractiondenomvgap", "fractiondenomdown", "fractiondelsize",
+ "limitabovevgap", "limitabovebgap", "limitabovekern",
+ "limitbelowvgap", "limitbelowbgap", "limitbelowkern",
+ "underdelimitervgap", "underdelimiterbgap",
+ "overdelimitervgap", "overdelimiterbgap",
+ "subshiftdrop", "supshiftdrop", "subshiftdown",
+ "subsupshiftdown", "subtopmax", "supshiftup",
+ "supbottommin", "supsubbottommax", "subsupvgap",
+ "spaceafterscript", "connectoroverlapmin",
+}
+
+tables.styles = {
+ "display",
+ "text",
+ "script",
+ "scriptscript",
+}
+
+function tables.stripmu(str)
+ str = string.gsub(str,"mu","")
+ str = string.gsub(str," ","")
+ str = string.gsub(str,"plus","+")
+ str = string.gsub(str,"minus","-")
+ return str
+end
+
+function tables.strippt(old)
+ local new = string.gsub(old,"pt","")
+ if new ~= old then
+ new = string.format("%0.4f",tonumber(new))
+ end
+ return new
+end
+
+function moduledata.math.parameters.showspacing()
+
+ local styles = tables.styles
+ local styleaxis = tables.styleaxis
+
+ context.starttabulate { "|Tl|Tl|" .. string.rep("Tc|",(#styles*2)) }
+ context.HL()
+ context.NC()
+ context.NC()
+ context.NC()
+ for i=1,#styles do
+ context.bold(styles[i])
+ context.NC()
+ context.bold("(cramped)")
+ context.NC()
+ end
+ context.NR()
+ context.HL()
+ for i=1,#styleaxis do
+ -- print(key,tex.getmath(key,"text"))
+ local one = styleaxis[i]
+ for j=1,#styleaxis do
+ local two = styleaxis[j]
+ context.NC()
+ if j == 1 then
+ context.bold(one)
+ end
+ context.NC()
+ context.bold(two)
+ context.NC()
+ for i=1,#styles do
+ context("\\ctxlua{context(math.tracing.spacing.tables.stripmu('\\the\\Umath%s%sspacing\\%sstyle'))}",one,two,styles[i])
+ context.NC()
+ context("\\ctxlua{context(math.tracing.spacing.tables.stripmu('\\the\\Umath%s%sspacing\\cramped%sstyle'))}",one,two,styles[i])
+ context.NC()
+ end
+ context.NR()
+ end
+ end
+ context.stoptabulate()
+end
+
+function moduledata.math.parameters.showparameters()
+
+ local styles = tables.styles
+ local parameters = tables.parameters
+
+ context.starttabulate { "|l|" .. string.rep("Tc|",(#styles*2)) }
+ context.HL()
+ context.NC()
+ context.NC()
+ for i=1,#styles do
+ context.bold(styles[i])
+ context.NC()
+ context.bold("(cramped)")
+ context.NC()
+ end
+ context.NR()
+ context.HL()
+ for i=1,#parameters do
+ local parameter = parameters[i]
+ -- print(parameter,tex.getmath(parameter,"text"))
+ context.NC()
+ context.type(parameter)
+ context.NC()
+ for i=1,#styles do
+ context("\\ctxlua{context(math.tracing.spacing.tables.strippt('\\the\\Umath%s\\%sstyle'))}",parameter,styles[i])
+ context.NC()
+ context("\\ctxlua{context(math.tracing.spacing.tables.strippt('\\the\\Umath%s\\cramped%sstyle'))}",parameter,styles[i])
+ context.NC()
+ end
+ context.NR()
+ end
+ context.stoptabulate()
+
+end
diff --git a/tex/context/modules/mkiv/s-math-parameters.mkiv b/tex/context/modules/mkiv/s-math-parameters.mkiv
new file mode 100644
index 000000000..f2fde5d83
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-parameters.mkiv
@@ -0,0 +1,41 @@
+%D \module
+%D [ file=s-math-parameters.mkiv,
+%D version=2012.12.05,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Math Parameters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[math-parameters]
+
+\registerctxluafile{s-math-parameters}{}
+
+\installmodulecommandluasingle \showmathspacing {moduledata.math.parameters.showspacing}
+\installmodulecommandluasingle \showmathparameters {moduledata.math.parameters.showparameters}
+
+\stopmodule
+
+\continueifinputfile{s-math-parameters.mkiv}
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=1cm,
+ topspace=1cm,
+ footer=0pt,
+ header=0pt]
+
+\setupbodyfont
+ [dejavu,8pt]
+
+\starttext
+
+ \showmathspacing \page
+ \showmathparameters \page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-math-repertoire.mkiv b/tex/context/modules/mkiv/s-math-repertoire.mkiv
new file mode 100644
index 000000000..230eb513e
--- /dev/null
+++ b/tex/context/modules/mkiv/s-math-repertoire.mkiv
@@ -0,0 +1,487 @@
+%D \module
+%D [ file=s-math-parameters.mkiv, % was s-mat-12.mkiv
+%D version=2012.06.06, % whatever, probably a bit earlier
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Math Character Repertoire,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[s][math-characters]
+
+% context --jit --global --bodyfont=lucidanova --result=math-repertoire-lucidanova s-math-repertoire.mkiv
+% context --jit --global --bodyfont=cambria --result=math-repertoire-cambria s-math-repertoire.mkiv
+% context --jit --global --bodyfont=xits --result=math-repertoire-xits s-math-repertoire.mkiv
+% context --jit --global --bodyfont=modern --result=math-repertoire-modern s-math-repertoire.mkiv
+% context --jit --global --bodyfont=pagella --result=math-repertoire-pagella s-math-repertoire.mkiv
+% context --jit --global --bodyfont=termes --result=math-repertoire-termes s-math-repertoire.mkiv
+% context --jit --global --bodyfont=bonum --result=math-repertoire-bonum s-math-repertoire.mkiv
+
+\startmodule[math-repertoire]
+
+% layout
+
+\definecolor[backgroundcolor] [r=.6,g=.6]
+\definecolor[backgroundcolorx][r=.6]
+\definecolor[backgroundcolory][g=.6]
+\definecolor[baselinecolor] [a=1,t=.5,s=.6]
+\definecolor[charactercolor] [b=.6]
+\definecolor[pagecolor] [s=.1]
+\definecolor[nonecolor] [s=.5]
+\definecolor[textcolor] [s=.9]
+
+% \setuppapersize[HD]
+%
+% \setuplayout
+% [page]
+
+\setuppapersize
+ [HD+]
+
+\setuplayout
+ [backspace=0pt,
+ topspace=0pt,
+ bottomspace=120pt, %1200-1080
+ bottom=24pt,
+ bottomdistance=5mm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\definelayer
+ [page]
+
+\setuplayer
+ [page]
+ [width=\textwidth,
+ height=\textheight]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=pagecolor]
+
+\setupbackgrounds
+ [text][text]
+ [bottomframe=on,
+ framecolor=textcolor,
+ rulethickness=0.025ex]
+
+\setupmakeup
+ [standard]
+ [pagestate=start]
+
+\setupinteraction
+ [state=start,
+ menu=on]
+
+\defineinteractionmenu
+ [ALPHABETS]
+ [bottom]
+
+\defineinteractionmenu
+ [alphabets]
+ [bottom]
+
+\defineinteractionmenu
+ [symbols]
+ [bottom]
+
+\setupinteractionmenu
+ [bottom]
+ [before=\vfill,
+ after=\vfill,
+ left=\hfill,
+ right=\hfill,
+ style=\tt\bf,
+ distance=0pt,
+ color=textcolor,
+ contrastcolor=nonecolor]
+
+\def\showmathcharacterssetrange#1#2#3%
+ {\writestatus{range}{#1: \unihex{#2} - \unihex{#3}}%
+ \ifcase#2\relax
+ \definereference[#1][notpresent]%
+ \else\ifcase#3\relax
+ \definereference[#1][notpresent]%
+ \else
+ \normalexpanded{\definereference[#1][\unihex{#2}]}%
+ \fi\fi}
+
+\startinteractionmenu[bottom]
+ \startgot [firstpage] first \stopgot \quad
+ \startgot [deltapage(-100)] -100 \stopgot \quad
+ \startgot [deltapage(-10)] -10 \stopgot \quad
+ \startgot [previouspage] previous \stopgot \quad
+ \startgot [nextpage] next \stopgot \quad
+ \startgot [deltapage(+10)] +10 \stopgot \quad
+ \startgot [deltapage(+100)] +100 \stopgot \quad
+ \startgot [lastpage] last \stopgot
+\stopinteractionmenu
+
+\startinteractionmenu[ALPHABETS]
+ \startgot [U+00041] NORMAL \stopgot \quad
+ \startgot [U+1D400] BOLD \stopgot \quad
+ \startgot [U+1D434] ITALIC \stopgot \quad
+ \startgot [U+1D468] BOLDITALIC \stopgot \quad
+ \startgot [U+1D49C] SCRIPT \stopgot \quad
+ \startgot [U+1D4D0] BOLDSCRIPT \stopgot \quad
+ \startgot [U+1D504] FRAKTUR \stopgot \quad
+ \startgot [U+1D538] DOUBLESTRUCK \stopgot \quad
+ \startgot [U+1D56C] BOLDFRAKTUR \stopgot \quad
+ \startgot [U+1D5A0] SS NORMAL \stopgot \quad
+ \startgot [U+1D5D4] SS BOLD \stopgot \quad
+ \startgot [U+1D608] SS ITALIC \stopgot \quad
+ \startgot [U+1D63C] SS BOLDITALIC \stopgot \quad
+ \startgot [U+1D670] MONOSPACE \stopgot \quad
+ \startgot [U+00391] GRK NORMAL \stopgot \quad
+ \startgot [U+1D6A8] GRK BOLD \stopgot \quad
+ \startgot [U+1D6E2] GRK ITALIC \stopgot \quad
+ \startgot [U+1D71C] GRK BOLDITALIC \stopgot \quad
+ \startgot [U+1D756] GRK SS BOLD \stopgot \quad
+ \startgot [U+1D790] GRK SS BOLDITALIC \stopgot
+\stopinteractionmenu
+
+\startinteractionmenu[alphabets]
+ \startgot [U+00061] normal \stopgot \quad
+ \startgot [U+1D41A] bold \stopgot \quad
+ \startgot [U+1D44E] italic \stopgot \quad
+ \startgot [U+1D482] bolditalic \stopgot \quad
+ \startgot [U+1D4B6] script \stopgot \quad
+ \startgot [U+1D4EA] boldscript \stopgot \quad
+ \startgot [U+1D51E] fraktur \stopgot \quad
+ \startgot [U+1D552] doublestruck \stopgot \quad
+ \startgot [U+1D586] boldfraktur \stopgot \quad
+ \startgot [U+1D5BA] ss normal \stopgot \quad
+ \startgot [U+1D5EE] ss bold \stopgot \quad
+ \startgot [U+1D622] ss italic \stopgot \quad
+ \startgot [U+1D656] ss bolditalic \stopgot \quad
+ \startgot [U+1D68A] monospace \stopgot \quad
+ \startgot [U+003B1] grk normal \stopgot \quad
+ \startgot [U+1D6C2] grk bold \stopgot \quad
+ \startgot [U+1D6FC] grk italic \stopgot \quad
+ \startgot [U+1D736] grk bolditalic \stopgot \quad
+ \startgot [U+1D770] grk ss bold \stopgot \quad
+ \startgot [U+1D7AA] grk ss bolditalic \stopgot
+\stopinteractionmenu
+
+% \startinteractionmenu[symbols]
+% \startgot [U+00030] dig normal \stopgot \quad
+% \startgot [U+1D7CE] dig bold \stopgot \quad
+% \startgot [U+1D7D8] dig doublestruck \stopgot \quad
+% \startgot [U+1D7E2] dig ss normal \stopgot \quad
+% \startgot [U+1D7EC] dig ss bold \stopgot \quad
+% \startgot [U+1D7F6] dig monospace \stopgot \quad
+% \startgot [U+02200] operators \stopgot \quad
+% \startgot [U+02701] symbols a \stopgot \quad
+% \startgot [U+02901] symbols b \stopgot \quad
+% \startgot [U+02A00] supplemental \stopgot \quad
+% \startgot [U+027F0] arrows a \stopgot \quad
+% \startgot [U+02900] arrows b \stopgot \quad
+% \startgot [U+1F800] arrows c \stopgot
+% \stopinteractionmenu
+
+\startinteractionmenu[symbols]
+ \startgot [U+00030] dig normal \stopgot \quad
+ \startgot [U+1D7CE] dig bold \stopgot \quad
+ \startgot [U+1D7D8] dig doublestruck \stopgot \quad
+ \startgot [U+1D7E2] dig ss normal \stopgot \quad
+ \startgot [U+1D7EC] dig ss bold \stopgot \quad
+ \startgot [U+1D7F6] dig monospace \stopgot \quad
+ \startgot [U+02200] operators \stopgot \quad
+ \startgot [miscellaneousmathematicalsymbolsa] symbols a \stopgot \quad
+ \startgot [miscellaneousmathematicalsymbolsb] symbols b \stopgot \quad
+ \startgot [supplementalmathematicaloperators] supplemental \stopgot \quad
+ \startgot [supplementalarrowsa] arrows a \stopgot \quad
+ \startgot [supplementalarrowsb] arrows b \stopgot \quad
+ \startgot [supplementalarrowsc] arrows c \stopgot \quad
+ \removeunwantedspaces
+\stopinteractionmenu
+
+\defineframed
+ [somedata]
+ [background=color,
+ backgroundcolor=textcolor,
+ %framecolor=charactercolor,
+ %rulethickness=1pt,
+ frame=off,
+ offset=1ex]
+
+% helpers
+
+\unexpanded\def\showmathcharacterstxt#1%
+ {{\tttf#1}}
+
+\unexpanded\def\showmathcharacterschr#1#2%
+ {\iffontchar\font#2\relax
+ \scale
+ [sx=#1,sy=#1]
+ {\dontleavehmode
+ \begingroup
+ \setbox\scratchbox\hbox{\charactercolor\char#2}%
+ \scratchdimen\wd\scratchbox
+ \ifdim\scratchdimen>\zeropoint
+ \backgroundline[backgroundcolor]{\box\scratchbox}%
+ \else\ifdim\scratchdimen<\zeropoint
+ \scratchdimen-\scratchdimen
+ \setbox\scratchbox\hbox to \scratchdimen{\hss\charactercolor\char#2}%
+ \backgroundline[backgroundcolorx]{\box\scratchbox}%
+ \else
+ \setbox\scratchbox\hbox to 1em{\hss\charactercolor\char#2}%
+ \scratchdimen\wd\scratchbox
+ \backgroundline[backgroundcolory]{\box\scratchbox}%
+ \fi\fi
+ \hskip-\scratchdimen
+ \baselinecolor\vrule width \scratchdimen height .05ex depth .05ex
+ \endgroup}%
+ \fi}
+
+\unexpanded\def\showmathcharactersmth#1#2%
+ {\setbox\scratchbox\hbox{\showmathcharacterschr{#1}{#2}}%
+ \ht\scratchbox\strutht
+ \dp\scratchbox\strutdp
+ \box\scratchbox}
+
+\let\showmathcharactersbodyfonts\empty
+
+\unexpanded\def\showmathcharactersbodyfontentry#1#2%
+ {\somedata
+ [align={none,middle},background=,height=5cm]
+ {\begingroup
+ \switchtobodyfont[#2,12pt]%
+ \definedfont[MathRoman*math-text]%
+ \showmathcharactersmth{10}{#1}%
+ \endgroup
+ \vfilll
+ \doifelsemode{crosslink}
+ {\goto{\strut\textcolor\showmathcharacterstxt{#2}}[#2::#1]}%
+ {\strut\textcolor\showmathcharacterstxt{#2}}}%
+ \hskip1ex}
+
+\unexpanded\def\showmathcharacterssetbodyfonts#1%
+ {\edef\showmathcharactersbodyfonts{#1}%
+ \def\doshowmathcharacterssetbodyfonts##1{\setupbodyfont[##1,12pt]}%
+ \processcommacommand[\showmathcharactersbodyfonts]\doshowmathcharacterssetbodyfonts}
+
+\unexpanded\def\showmathcharactersbodyfontschars#1%
+ {\processcommacommand[\showmathcharactersbodyfonts]{\showmathcharactersbodyfontentry{#1}}}
+
+% main
+
+\unexpanded\def\showmathcharactersstart
+ {\starttext
+ \startstandardmakeup % we use baselinecolor so that we have a transparency on page 1
+ \setupalign[middle]
+ \vfil
+ \dontleavehmode \scale[height=.3\textheight]{\strut\color[textcolor]{\fontclass}}
+ \vfil
+ \dontleavehmode \scale[height=.1\textheight]{\strut\color[baselinecolor]{\currentdate}}
+ \vfil
+ \vfil
+ \stopstandardmakeup}
+
+\unexpanded\def\showmathcharactersstop
+ {\stoptext}
+
+% entry
+
+\unexpanded\def\showmathcharactersstartentry
+ {\startstandardmakeup}
+
+\unexpanded\def\showmathcharactersstopentry
+ {\tightlayer[page]
+ \stopstandardmakeup}
+
+\unexpanded\def\showmathcharactersreference#1%
+ {\setlayer[page]{\pagereference[#1]}}
+
+\unexpanded\def\showmathcharactersentryhexdectit#1#2#3%
+ {\setlayer
+ [page]
+ [preset=middletop,voffset=5mm]
+ {\somedata[height=1cm]{\showmathcharacterstxt{#1}}}
+ \setlayer
+ [page]
+ [preset=middle,y=2cm]
+ {\showmathcharactersmth{25}{#2}}
+ \setlayer
+ [page]
+ [preset=righttop,offset=5mm]
+ {\somedata[height=1cm]{\showmathcharacterstxt{#3}}}
+ \doifsomething\showmathcharactersbodyfonts
+ {\setlayer
+ [page]
+ [preset=middlebottom,voffset=5mm]
+ {\showmathcharactersbodyfontschars{#2}}}}
+
+% dimensions
+
+\unexpanded\def\showmathcharactersentrywdhtdpic#1#2#3#4%
+ {\setlayer
+ [page]
+ [preset=leftbottom,offset=5mm]
+ {\somedata[align=normal,width=5cm]
+ {\strut width \hfill \the\dimexpr#1sp\par
+ \strut height\hfill \the\dimexpr#2sp\par
+ \strut depth \hfill \the\dimexpr#3sp\par
+ \strut italic\hfill \the\dimexpr#4sp}}}
+
+\unexpanded\def\showmathcharactersentryresource#1%
+ {} % {virtual: #1\par}
+
+% next
+
+\unexpanded\def\showmathcharactersstartnext
+ {\setlayer
+ [page]
+ [preset=middleleft,hoffset=5mm]
+ \bgroup\vbox\bgroup}
+
+\unexpanded\def\showmathcharactersstopnext
+ {\egroup\egroup}
+
+\unexpanded\def\showmathcharactersnextentry#1#2#3%
+ {\ifnum#1>1 \vskip1ex \fi
+ \dontleavehmode\somedata
+ [align=normal,width=4cm]
+ {\strut\showmathcharacterstxt{#2}\hfill\showmathcharacterschr{2}{#3}}\par}
+
+\unexpanded\def\showmathcharactersnextcycle#1%
+ {\ifnum#1>1 \vskip1ex \fi
+ \dontleavehmode\somedata
+ [align=normal,width=4cm]
+ {\strut\showmathcharacterstxt{cycle}}\par}
+
+% variants
+
+\unexpanded\def\showmathcharactersstartvvariants
+ {\setlayer
+ [page]
+ [preset=lefttop,offset=5mm]
+ \bgroup\vbox\bgroup}
+
+\unexpanded\def\showmathcharactersstarthvariants
+ {\setlayer
+ [page]
+ [preset=lefttop,offset=5mm]
+ \bgroup\hbox\bgroup}
+
+\unexpanded\def\showmathcharactersvvariantsentry#1#2#3%
+ {\ifnum#1>1 \vskip1ex \fi
+ \dontleavehmode\somedata
+ [align=middle,width=4cm]
+ {\strut\showmathcharacterstxt{#2}\hfilll\showmathcharacterschr{2}{#3}}}
+
+\unexpanded\def\showmathcharactershvariantsentry#1#2#3%
+ {\ifnum#1>1 \hskip1ex \else \dontleavehmode \fi
+ \somedata
+ [align={none,middle},height=2cm]
+ {\strut\showmathcharacterstxt{#2}\vfilll\showmathcharacterschr{2}{#3}}}
+
+\unexpanded\def\showmathcharactersstopvvariants
+ {\egroup\egroup}
+
+\unexpanded\def\showmathcharactersstophvariants
+ {\egroup\egroup}
+
+\unexpanded\def\showmathcharactersbetweennextandvariants
+ {}
+
+% classes
+
+\unexpanded\def\showmathcharactersstartentryclassspec
+ {\setlayer
+ [page]
+ [preset=rightbottom,offset=5mm]
+ \bgroup\somedata[align=normal,width=8cm]\bgroup}
+
+\unexpanded\def\showmathcharactersstopentryclassspec
+ {\egroup\egroup}
+
+\unexpanded\def\showmathcharactersentryclassname#1#2%
+ {\strut{\showmathcharacterstxt#1}\hfill\showmathcharacterstxt{#2}\par}
+
+% symbols
+
+\unexpanded\def\showmathcharactersentrysymbol#1#2%
+ {\setlayer
+ [page]
+ [preset=leftbottom,hoffset=5mm,voffset=50mm]
+ {\somedata
+ [align=normal,width=5cm]
+ {\showmathcharacterstxt{#1}\hfill\showmathcharacterschr{4}{#2}}}}
+
+% alternates
+
+\unexpanded\def\showmathcharactersstartlookupvariants
+ {\setlayer
+ [page]
+ [preset=middleright,hoffset=5mm]
+ \bgroup\vbox\bgroup}
+
+\unexpanded\def\showmathcharactersstoplookupvariants
+ {\egroup\egroup}
+
+\unexpanded\def\showmathcharacterslookupvariant#1#2#3#4%
+ {\ifnum#1>1 \vskip1ex \fi
+ \somedata
+ [align=normal,width=7cm]
+ {\showmathcharacterstxt{#4:} \showmathcharacterstxt{#2}\hfill\showmathcharacterschr{4}{#3}}}
+
+% main
+
+% this is a one-run style so we can forget about an alternative
+% just assume that the previous definitions are global
+
+\unprotect
+
+\unexpanded\def\showmathfontrepertoire
+ {\dosingleempty\module_math_repertoire_show}
+
+\def\module_math_repertoire_show[#1]%
+ {\showmathfontcharacters[alternative=,option=,check=yes,#1]
+ \showmathfontcharacters[alternative=,option=,#1]}
+
+\protect
+
+\stopmodule
+
+\continueifinputfile{s-math-repertoire.mkiv}
+
+\showmathcharacterssetbodyfonts{lucidaot,cambria,xits,modern,pagella,termes,bonum,schola,dejavu}
+
+\starttext
+
+ \doifelse {\getdocumentargument{bodyfont}} {} {
+
+ % \setupbodyfont[cambria, 12pt]
+ % \setupbodyfont[modern, 12pt]
+ % \setupbodyfont[lmvirtual, 12pt]
+ % \setupbodyfont[pxvirtual, 12pt]
+ % \setupbodyfont[txvirtual, 12pt]
+ % \setupbodyfont[palatino, 10pt]
+ % \setupbodyfont[mathtimes, 12pt]
+ % \setupbodyfont[stix, 12pt]
+ % \setupbodyfont[xits, 12pt]
+ % \setupbodyfont[lucida, 12pt]
+ % \setupbodyfont[lucidaot, 12pt]
+ % \setupbodyfont[pagella, 12pt]
+ % \setupbodyfont[bonum, 12pt]
+ % \setupbodyfont[schola, 12pt]
+ \setupbodyfont[dejavu, 12pt]
+
+ } {
+
+ \normalexpanded{\setupbodyfont[\getdocumentargument{bodyfont},12pt]}
+
+ }
+
+ \showmathfontrepertoire
+
+\stoptext
+
diff --git a/tex/context/modules/mkiv/s-mod-00.mkiv b/tex/context/modules/mkiv/s-mod-00.mkiv
new file mode 100644
index 000000000..7af56dc2d
--- /dev/null
+++ b/tex/context/modules/mkiv/s-mod-00.mkiv
@@ -0,0 +1,24 @@
+%D \module
+%D [ file=s-mod-00,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Documentation Base Environment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\startmode[nocode]
+
+ % \definieerbuffer[definition] % ignore
+
+ \def\startdefinition#1\stopdefinition{}
+
+\stopmode
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-mod-01.mkiv b/tex/context/modules/mkiv/s-mod-01.mkiv
new file mode 100644
index 000000000..6946bef69
--- /dev/null
+++ b/tex/context/modules/mkiv/s-mod-01.mkiv
@@ -0,0 +1,390 @@
+%D \module
+%D [ file=s-mod-01,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Module Documentation,
+%D author={Hans Hagen \& Luigi Scarso},
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+%D Usage:
+%D
+%D \starttyping
+%D context --ctx=s-mod somefile.mkiv
+%D \stoptyping
+%D
+%D In due time there will be a \type {mtx-context-module} as well.
+%D
+%D Luigi Scarso coordinates the processing of modules so best contact
+%D him when you run into problems. Bugs in this style can be sent to
+%D Hans.
+
+\usemodule
+ [abr-00]
+
+\setvariables
+ [document]
+ [ file=\jobname,
+ type=unknown,
+ version={\currentdate[\v!year,{.},\v!month,{.},\v!day]},
+ system=\CONTEXT,
+ title=Unknown Title,
+ subtitle=,
+ author=Unknown Author,
+ date=\currentdate,
+ copyright=Unknown Copyright,
+ suggestions=]
+
+\let\module\setupdocument
+
+\definepalet [module:unknown] [localone=black,localtwo=white]
+
+\definepalet [module:tex] [localone=blue,localtwo=green]
+\definepalet [module:mkii] [localone=blue,localtwo=green]
+\definepalet [module:mkiv] [localone=blue,localtwo=green]
+\definepalet [module:mkvi] [localone=blue,localtwo=green]
+
+\definepalet [module:lua] [localone=red,localtwo=green]
+\definepalet [module:cld] [localone=red,localtwo=green]
+
+\definepalet [module:mp] [localone=red,localtwo=blue]
+\definepalet [module:mpii] [localone=red,localtwo=blue]
+\definepalet [module:mpiv] [localone=red,localtwo=blue]
+\definepalet [module:metapost][localone=red,localtwo=blue]
+
+\setuppalet
+ [module:unknown]
+
+\startuseMPgraphic{page}
+
+ StartPage ;
+
+ color local_white ; local_white := .8white ;
+ color local_one ; local_one := \MPcolor{localone} randomized (.6,.8) ;
+ color local_two ; local_two := \MPcolor{localtwo} randomized (.3,.4) ;
+
+ color local_one ; local_one := .75[\MPcolor{localone},white] ;
+ color local_two ; local_two := .75[\MPcolor{localtwo},white] ;
+
+ numeric width ; width := bbwidth Page ;
+ numeric height ; height := bbheight Page ;
+
+ u := width/400 ;
+
+ def a_module (expr dx, dy) =
+ picture p ; p := image (
+ ddy := 0 ; sx := 60u ;
+ for i=1 upto (4 randomized 2) :
+ sy := 7u randomized 3u ;
+ fill unitsquare xyscaled(sx,sy) shifted (0,ddy) withcolor local_two ;
+ ddy := ddy + sy + 4u ;
+ endfor ;
+ ) ;
+ p := p shifted (dx,dy) shifted - center p ;
+ fill boundingbox p enlarged 8u withcolor local_white ;
+ fill boundingbox p enlarged 4u withcolor local_one ;
+ draw p ;
+ enddef ;
+
+ set_grid(width, height, width/15, height/15) ;
+
+ forever:
+ if new_on_grid(uniformdeviate width,uniformdeviate height):
+ a_module(dx,dy) ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+
+ picture p ;
+
+ draw image (
+ draw anchored.urt(textext("\bf\strut\documentvariable{system}") ysized 5.0cm,urcorner Page shifted (-1cm,- 1cm)) ;
+ draw anchored.urt(textext("\bf\strut\documentvariable{title}") ysized 1.5cm,urcorner Page shifted (-1cm,- 8cm)) ;
+ draw anchored.urt(textext("\bf\strut\documentvariable{subtitle}") ysized 1.5cm,urcorner Page shifted (-1cm,-10cm)) ;
+ draw anchored.urt(textext("\bf\strut\documentvariable{author}") ysized 1.5cm,lrcorner Page shifted (-1cm, 5cm)) ;
+ draw anchored.urt(textext("\bf\strut\currentdate") ysized 1.5cm,lrcorner Page shifted (-1cm, 3cm)) ;
+ ) withcolor .25white ;
+
+ StopPage ;
+
+\stopuseMPgraphic
+
+\startsetups[document:start]
+
+ \setuppalet
+ [module:\documentvariable{type}]
+
+ \startTEXpage
+ \useMPgraphic{page}
+ \stopTEXpage
+
+ \page[right]
+
+\stopsetups
+
+\startsetups[document:stop]
+
+ \page
+
+ \placeregister
+ [\v!index]
+ [\c!balance=\v!yes,
+ \c!indicator=\v!no,
+ \c!criterium=\v!text]
+
+\stopsetups
+
+% In order to be able to typeset this one too, we need to avoid
+% direct backslashed names.
+
+\starttexdefinition startmoduledocumentation
+ \starttext
+ \page
+ \begingroup
+ \startdocument
+\stoptexdefinition
+
+\starttexdefinition stopmoduledocumentation
+ \stopdocument
+ \page
+ \endgroup
+ \stoptext
+\stoptexdefinition
+
+\starttexdefinition startdocumentation
+ \par
+ \bgroup
+\stoptexdefinition
+
+\starttexdefinition stopdocumentation
+ \par
+ \egroup
+\stoptexdefinition
+
+\definetyping
+ [definition]
+
+\starttexdefinition startcompressdefinitions
+ \blank
+ \begingroup
+ \setuptyping[definition][bodyfont=small]
+\stoptexdefinition
+
+\starttexdefinition stopcompressdefinitions
+ \blank
+ \endgroup
+\stoptexdefinition
+
+\definetyping [PL] [\c!option=PL]
+\definetyping [JV] [\c!option=JV]
+\definetyping [MP] [\c!option=MP]
+\definetyping [TEX] [\c!option=TEX]
+\definetyping [LUA] [\c!option=LUA]
+
+\setuptyping [\v!typing] [\c!margin=\v!standard]
+\setuptyping [\v!file] [\c!margin=\v!standard]
+\setuptyping [definition] [\c!margin=0pt,\c!numbering=\v!line,\c!continue=\v!yes] % this continue wins
+
+\setuplinenumbering
+ [definition]
+ [\c!style=\ttx,
+ \c!distance=\leftmargindistance,
+ \c!align=\v!flushright]
+
+% This will be cleaned up.
+
+\unexpanded\def\domodulemarginstuff#1#2%
+ {\marginstuff
+ {\ifx#1\relax
+ \index{#2}%
+ \else
+ \index{#1{#2}}%
+ \fi
+ #1{\doboundtext{#2}{\leftmarginwidth}{..}}}}
+
+\unexpanded\def\modulemarginstuff#1#2% to be renamed
+ {\processcommalist[#2]{\domodulemarginstuff#1}}
+
+\definemargindata
+ [marginstuff]
+ [left]
+ [stack=yes,
+ hoffset=2em,
+ style=\ttxx]
+
+\unexpanded\def\macros {\modulemarginstuff\tex }
+\unexpanded\def\extras {\modulemarginstuff\relax}
+\unexpanded\def\elements{\modulemarginstuff\someelement}
+
+\unexpanded\def\someelement#1{\type{<#1>}}
+
+% [index]{command}
+
+% \macros{a,b}
+% \macros{a,b}{b}
+% \macros[a]{a,b}{b}
+
+% weg ermee (indeed):
+%
+% \defineparagraphs [interface] [\c!n=2]
+% \setupparagraphs [interface] [1] [\c!width=4cm]
+
+\starttexdefinition startexample
+ \par
+ \startnarrower
+\stoptexdefinition
+
+\starttexdefinition stopexample
+ \stopnarrower
+\stoptexdefinition
+
+%D Command references:
+
+\usemodule[int-load] \loadsetups
+
+\let\showsetup\setup
+
+\setupframedtexts
+ [setuptext]
+ [\c!background=\v!screen,
+ \c!frame=\v!off]
+
+% style (we use dejavu as it supports more characters)
+
+\switchtobodyfont
+ [dejavu-condensed,10pt] % preload
+
+\setupbodyfont
+ [dejavu,10pt] % main font
+
+\mainlanguage
+ [en]
+
+\setuptyping
+ [\v!typing]
+ [\c!bodyfont=dejavu-condensed]
+
+\setupwhitespace
+ [\v!big]
+
+\setuptolerance
+ [\v!verytolerant,\v!stretch]
+
+\setuplayout
+ [\c!backspace=3.5cm,
+ \c!leftmargin=1.75cm,
+ \c!rightmargin=0cm,
+ \c!margindistance=.5cm,
+ \c!leftedgedistance=.25cm,
+ \c!rightedgedistance=.5cm,
+ \c!edge=1.5cm,
+ \c!width=15.55333cm, % 13.998cm at 9pt => 15.55333 at 10pt
+ \c!topspace=2cm,
+ \c!header=1.25cm,
+ \c!footer=1.25cm,
+ \c!height=middle,
+ \c!style=\ss]
+
+\setuppagenumbering
+ [\c!location=]
+
+\setuppagenumbering
+ [\c!alternative={\v!doublesided,\v!singlesided}]
+
+\setupfootertexts
+ [\v!edge]
+ [][\pagenumber]
+
+\setupfootertexts
+ [\v!margin]
+ [\filename{\documentvariable{file}}][]
+ [\filename{\documentvariable{file}}][]
+
+\setupfootertexts
+ [\v!text]
+ [\CONTEXT]
+ [\documentvariable{title}]
+
+\setupheadertexts
+ [\v!text]
+ []
+ [\documentvariable{subtitle}]
+
+\setupinmargin
+ [\c!location=\v!left]
+
+\setupheads
+ [\c!alternative=\v!inmargin]
+
+\setuphead
+ [\v!chapter]
+ [\c!style=\bfc,
+ \c!page=\v!right,
+ \c!header=\v!empty]
+
+\setuphead
+ [\v!section]
+ [\c!style=\bfb,
+ \c!page=\v!right]
+
+\setuphead
+ [\v!subsection]
+ [\c!style=\bfa]
+
+\setuplist
+ [\v!chapter]
+ [\c!style=\v!bold,
+ \c!after=\blank]
+
+\setupcombinedlist
+ [\v!content]
+ [\c!width=3em,
+ \c!aligntitle=\v!yes]
+
+\setupregister
+ [\v!index]
+ [\c!balance=\v!yes,
+ \c!indicator=\v!no]
+
+\setupinteraction
+ [\c!state=\v!start,
+ \c!color=,
+ \c!contrastcolor=,
+ \c!style=]
+
+% modes
+
+\doifmode {nocolor} {
+
+ \setupcolors
+ [\c!conversion=\v!always]
+
+}
+
+\doifmode {singlesided} {
+
+ \setuppagenumbering
+ [\c!alternative=\v!singlesided]
+
+ \setupfootertexts
+ [\v!margin]
+ [\filename{\documentvariable{file}}][]
+
+}
+
+% bonus
+
+\usemodule
+ [abr-02]
+
+% another one
+
+\dontcomplain
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-mod-02.mkiv b/tex/context/modules/mkiv/s-mod-02.mkiv
new file mode 100644
index 000000000..37e3d2f14
--- /dev/null
+++ b/tex/context/modules/mkiv/s-mod-02.mkiv
@@ -0,0 +1,24 @@
+%D \module
+%D [ file=s-mod-02,
+%D version=very-old,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Documentation Screen Environment,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\startmode[nocode]
+
+ % \definieerbuffer[definition] % ignore
+
+ \def\startdefinition#1\stopdefinition{}
+
+\stopmode
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-pages-statistics.mkiv b/tex/context/modules/mkiv/s-pages-statistics.mkiv
new file mode 100644
index 000000000..375dd9949
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pages-statistics.mkiv
@@ -0,0 +1,134 @@
+%D \module
+%D [ file=s-pages-statistics, % s-otr-01,
+%D version=2012.02.02,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Page Statistics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\defineframed
+ [otrstatistics]
+ [\c!offset=\bodyfontsize,
+ \c!background=\v!color,
+ \c!strut=\v!no,
+ \c!backgroundcolor=white,
+ \c!frame=\v!off,
+ \c!align=\v!middle]
+
+\definecombination
+ [otrstatistics]
+ [\c!nx=2,
+ \c!ny=2,
+ \c!location=\v!top]
+
+% expansion is neeed because tabulate sets some penalties
+
+\startsetups system:page:otr:statistics
+ \normalexpanded {
+ \startcombination[otrstatistics] {
+ \otrstatistics {
+ \starttabulate[|Tw(10em)|Trw(8em)|]
+ \NC \string\textwidth \NC \the\textwidth \NC \NR
+ \NC \string\textheight \NC \the\textheight \NC \NR
+ \NC \string\lineheight \NC \the\lineheight \NC \NR
+ \NC \string\strutheight \NC \strutheight \NC \NR
+ \NC \string\strutdepth \NC \strutdepth \NC \NR
+ % \NC \string\vsize \NC \the\vsize \NC \NR
+ \NC \string\topskip \NC \the\topskip \NC \NR
+ \stoptabulate
+ }
+ } {}
+ {
+ \otrstatistics {
+ \starttabulate[|Tw(10em)|Trw(8em)|]
+ \NC \string\pagegoal \NC \the\pagegoal \NC \NR
+ \NC \string\pagetotal \NC \the\pagetotal \NC \NR
+ \NC \string\pagedepth \NC \the\pagedepth \NC \NR
+ \NC \string\pageshrink \NC \the\pageshrink \NC \NR
+ \NC \string\pagestretch \NC \the\pagestretch \NC \NR
+ \NC \string\pagefilstretch \NC \the\pagefilstretch \NC \NR
+ \NC \string\pagefillstretch \NC \the\pagefillstretch \NC \NR
+ \NC \string\pagefilllstretch \NC \the\pagefilllstretch \NC \NR
+ \stoptabulate
+ }
+ } {}
+ {
+ \otrstatistics {
+ \starttabulate[|Tw(10em)|Trw(8em)|]
+ \NC \string\widowpenalty \NC \the\widowpenalty \NC \NR
+ \NC \string\clubpenalty \NC \the\clubpenalty \NC \NR
+ \NC \string\displaywidowpenalty \NC \the\displaywidowpenalty \NC \NR
+ \NC \string\brokenpenalty \NC \the\brokenpenalty \NC \NR
+ \NC \string\interlinepenalty \NC \the\interlinepenalty \NC \NR
+ \stoptabulate
+ }
+ } {}
+ {
+ \otrstatistics[\c!foregroundcolor=darkred] {
+ \starttabulate[|Tw(10em)|Trw(8em)|]
+ \NC page \NC \the\realpageno \NC \NR
+ \NC delta \NC \the\dimexpr\pagegoal-\pagetotal\relax \NC \NR
+ \stoptabulate
+ }
+ } {}
+ \stopcombination
+ }
+\stopsetups
+
+\defineoverlay
+ [system:page:otr:statistics]
+ [{\framed
+ [\c!offset=\bodyfontsize,
+ \c!background=\v!color,
+ \c!strut=\v!no,
+ %\c!frame=\v!off,
+ \c!framecolor=white,
+ \c!frameoffset=\onepoint,
+ \c!rulethickness=2\onepoint,
+ \c!backgroundcolor=darkblue,
+ \c!align=\v!middle]
+ {\forgetall
+ \insidefloattrue
+ \setups{system:page:otr:statistics}}}]
+
+\unexpanded\def\page_one_command_package_show_state_indeed
+ {\scratchheight\ht\b_page_one_contents
+ \scratchdepth \dp\b_page_one_contents
+ \setbox\b_page_one_contents\vbox\framed
+ [\c!offset=\v!overlay,
+ \c!framecolor=darkred,
+ \c!rulethickness=\onepoint,
+ \c!background={\v!foreground,system:page:otr:statistics}]
+ {\lower\scratchdepth\box\b_page_one_contents}%
+ \ht\b_page_one_contents\scratchheight
+ \dp\b_page_one_contents\scratchdepth}
+
+\let\page_one_command_package_show_state\relax
+
+\unexpanded\def\showpageproperties
+ {\let\page_one_command_package_show_state\page_one_command_package_show_state_indeed}
+
+\protect
+
+\continueifinputfile{s-pages-statistics.mkiv}
+
+\setupbodyfont[dejavu,11pt] \dontcomplain \showpageproperties
+
+\starttext
+
+\dorecurse {100} { \input tufte
+
+ \startitemize[packed,intro]
+ \startitem test \stopitem \startitem test \stopitem
+ \startitem test \stopitem \startitem test \stopitem
+ \stopitemize
+}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-physics-units.mkiv b/tex/context/modules/mkiv/s-physics-units.mkiv
new file mode 100644
index 000000000..50adc8014
--- /dev/null
+++ b/tex/context/modules/mkiv/s-physics-units.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=s-physics-units, % s-phy-01,
+%D version=2011-11-24,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Physics Units,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[physics-units]
+
+\registerctxluafile{s-physics-units}{}
+
+\installmodulecommandluasingle \showunits {moduledata.physics.units.showlist}
+
+\stopmodule
+
+\continueifinputfile{s-physics-units.mkiv}
+
+\usemodule[art-01]
+
+\starttext
+
+ \showunits
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-pre-17.mkiv b/tex/context/modules/mkiv/s-pre-17.mkiv
new file mode 100644
index 000000000..9c46b4ed7
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-17.mkiv
@@ -0,0 +1,408 @@
+%D \module
+%D [ file=s-pre-17,
+%D version=1999.08.20,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 17,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setupbodyfont
+ [dejavu,11pt,ss]
+
+\setupsystem
+ [random=medium]
+
+\setupbackgrounds
+ [state=repeat]
+
+\setupbackgrounds
+ [page]
+ [background={page,forward}]
+
+\setupbackgrounds
+ [text][text]
+ [background=blowdown]
+
+\setupinteraction
+ [state=start,
+% click=off,
+ color=TitleColor,
+ contrastcolor=TitleColor]
+
+\setupinteractionscreen
+ [option=max]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+\definecolor [BackColor] [s=.30]
+\definecolor [PageColor] [g=1]
+\definecolor [FrameColor] [r=1]
+\definecolor [TitleColor] [y=1]
+\definecolor [ArrowColor] [b=1]
+
+\defineoverlay [title] [\useMPgraphic{title}]
+\defineoverlay [page] [\useMPgraphic{page}]
+\defineoverlay [blowup] [{\hboxreference[whatever:\CurrentBlaBla]{\overlaybutton{whatever:\CurrentBlaBla}}}]
+\defineoverlay [blowdown] [{\hboxreference[page:\realfolio]{\overlaybutton{page:\realfolio}}}]
+\defineoverlay [forward] [\overlaybutton{forward}]
+
+\startMPinclusions
+ input "mp-abck.mpiv" ;
+\stopMPinclusions
+
+\startMPpositiongraphic{mppos:connection}
+ path pa, pb, pc ; pair ca, cb ;
+ initialize_box(\MPpos{\MPvar{self}}) ; pa := pxy ; ca := cxy ;
+ initialize_box(\MPpos{\MPvar{prev}}) ; pb := pxy ; cb := cxy ;
+ pickup pencircle scaled .5pt ;
+ pa := pa enlarged 10pt ;
+ pb := pb enlarged 10pt ;
+ for i=1 upto 10 :
+ draw pa randomized 20pt withcolor \MPcolor{FrameColor} ;
+ endfor ;
+ if \MPp{\MPvar{prev}} > 0 :
+ pair a, b, c, d ;
+ for i=1 upto 25 :
+ a := .5[ulcorner pa,urcorner pa] randomized (10pt,10pt) ;
+ b := .5[llcorner pb,lrcorner pb] randomized (20pt,10pt) ;
+ c := .5[a,b] rotatedaround(a,-25) randomized (5pt,5pt) ;
+ d := .5[a,b] rotatedaround(a,+25) randomized (5pt,5pt) ;
+ draw (a--b) withcolor \MPcolor{ArrowColor} ;
+ draw (d--a--c) withcolor \MPcolor{ArrowColor} ;
+ endfor ;
+ fi ;
+ anchor_box(\MPanchor{\MPvar{self}}) ;
+\stopMPpositiongraphic
+
+\startuseMPgraphic{title}
+ pickup pencircle scaled .5pt ;
+ for i=1 upto 10 :
+ draw fullsquare
+ xyscaled(OverlayWidth,OverlayHeight)
+ enlarged 10pt randomized 20pt
+ withcolor \MPcolor{TitleColor} ;
+ endfor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{page}
+ StartPage ;
+ pickup pencircle scaled .5pt ;
+ fill Page withcolor \MPcolor{BackColor} ;
+ for i=1 upto 20 :
+ draw Page enlarged -50pt randomized 50pt withcolor \MPcolor{PageColor} ;
+ endfor ;
+ StopPage ;
+\stopuseMPgraphic
+
+\newcounter\CurrentBlaBla
+
+\defineframedtext
+ [ZoomText]
+ [before=,
+ after=,
+ width=fit,
+ align=flushleft,
+ frame=off,
+ foregroundcolor=white]
+
+\starttexdefinition StartText
+ \begingroup
+ \getrandomdimen\scratchdimen{250pt}{350pt}
+ \edef\TextWidth{\the\scratchdimen}
+ \setbox\scratchbox\hbox\bgroup
+ \hsize\TextWidth
+ \ZoomText\bgroup
+\stoptexdefinition
+
+\starttexdefinition StartTextSimple
+ \begingroup
+ \setbox\scratchbox\hbox\bgroup
+ \framed [
+ frame=off,
+ foregroundcolor=white
+ ]
+ \bgroup
+\stoptexdefinition
+
+\starttexdefinition StopTextSimple
+ \StopText
+\stoptexdefinition
+
+\starttexdefinition StopText
+ \egroup
+ \egroup
+ \doglobal\increment\CurrentBlaBla
+ \let\PrevBlaBla\CurrentBlaBla \doglobal\decrement\PrevBlaBla
+ \let\NextBlaBla\CurrentBlaBla \doglobal\increment\NextBlaBla
+ \setMPpositiongraphic {
+ connection:\CurrentBlaBla
+ }{
+ mppos:connection
+ }{
+ seed=\CurrentBlaBla,
+ prev=connection:\PrevBlaBla,
+ next=connection:\NextBlaBla
+ }
+ \hbox to 600pt \bgroup
+ \setupinteraction[focus=fitr]
+ \getrandomdimen\scratchdimen{50pt}{75pt}
+ \hskip0pt plus \scratchdimen minus \scratchdimen
+ \hpos {
+ connection:\CurrentBlaBla
+ }{
+ \framed [
+ frame=off,
+ offset=overlay,
+ backgroundoffset=50pt,
+ background=blowup
+ ] {
+ \box\scratchbox
+ }
+ }
+ \getrandomdimen\scratchdimen{50pt}{75pt}
+ \hskip0pt plus \scratchdimen minus \scratchdimen
+ \egroup
+ \getrandomdimen\scratchdimen{75pt}{125pt}
+ \vskip\scratchdimen
+ \endgroup
+\stoptexdefinition
+
+\dontcomplain
+
+\disablemode[SpreadPage]
+
+\starttexdefinition StartPage #1
+ \doglobal\increment(\CurrentBlaBla,100)%
+ \setvariables[StartPage][title={#1}]
+ \setbox\scratchbox\hbox\bgroup
+ \valign\bgroup
+ \ignorespaces
+ \alignmark\alignmark
+ \vss
+ \cr
+\stoptexdefinition
+
+\starttexdefinition StopPage
+ \cr
+ \egroup
+ \egroup
+ \setbox\scratchbox\vbox\bgroup
+ \vskip100pt
+ \doifelsemode {SpreadPage} {
+ \hbox spread 200pt
+ } {
+ \hbox to \wd\scratchbox
+ }
+ \bgroup
+ \setupinteraction[focus=fitr]
+ \hss
+ \switchtobodyfont[big]%
+ \bfd
+ \doglobal\increment\CurrentBlaBla
+ \setupinterlinespace
+ \hpos {
+ title:\realfolio
+ }{
+ \framed [
+ frame=off,
+ offset=overlay,
+ backgroundoffset=50pt,
+ background=blowup
+ ] {
+ \framed [
+ frame=off,
+ align=middle,
+ foregroundcolor=white,
+ background=title
+ ] {
+ \getvariable{StartPage}{title}
+ }
+ }
+ }
+ \hss
+ \egroup
+ \vskip100pt
+ \box\scratchbox
+ \egroup
+ \normalexpanded {
+ \definepapersize [
+ MasterPage
+ ] [
+ width=\the\dimexpr\wd\scratchbox+100pt\relax,
+ height=\the\dimexpr\ht\scratchbox+\dp\scratchbox+100pt\relax
+ ]
+ }
+ \setuppapersize
+ [MasterPage]
+ [MasterPage]
+ \setuplayout [
+ topspace=25pt,
+ backspace=25pt,
+ width=middle,
+ header=0pt,
+ footer=0pt,
+ height=middle
+ ]
+ \centerbox {
+ \box\scratchbox
+ }
+ \page
+\stoptexdefinition
+
+\starttexdefinition StartTopic #1
+ \removeunwantedspaces
+ \cr
+ \doglobal\increment(\CurrentBlaBla,100)%
+ \vbox\bgroup
+ \vskip100pt
+ \bgroup
+ \definecolor[FrameColor][TitleColor]
+ \switchtobodyfont[big]
+ \bfd
+ \setupinterlinespace
+ \StartTextSimple
+ \ignorespaces
+ #1
+ \removeunwantedspaces
+ \StopTextSimple
+ \vskip25pt
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition StopTopic
+ \vskip-\lastskip
+ \vskip100pt
+ \egroup
+ \ignorespaces
+\stoptexdefinition
+
+\starttexdefinition TitlePage #1
+ \begingroup
+ \def\\{\vskip1ex\bfc\def\\{\vskip1ex\bfb}}
+ \enablemode[SpreadPage]
+ \StartPage{#1}
+ \StopPage
+ \endgroup
+\stoptexdefinition
+
+\continueifinputfile{s-pre-17.mkiv}
+
+\starttext
+
+\nopdfcompression
+
+\TitlePage{About Text\\Today's Talk\\Hans Hagen}
+
+\StartPage{The First Page}
+
+ \StartTopic{Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+ \StopTopic
+
+ \StartTopic{Another Text}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+ \StopTopic
+
+ \StartTopic{Some More Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StopTopic
+
+ \StartTopic{Some Text Again}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+ \StartText \input knuth \StopText
+ \StartText \input tufte \StopText
+ \StopTopic
+
+\StopPage
+
+\StartPage{The Second Page}
+
+ \StartTopic{Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+ \StartTopic{Another Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+ \StartTopic{Some Nice Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input tufte \StopText
+ \StopTopic
+
+ \StartTopic{Some Funny Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StopTopic
+
+ \StartTopic{Quite Some Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+ \StartTopic{Even More Text}
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+\StopPage
+
+\StartPage{The Third Page}
+
+ \StartTopic{Some Short Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+ \StartTopic{Some Minimal Text}
+ \StartText \input tufte \StopText
+ \StartText \input zapf \StopText
+ \StopTopic
+
+ \StartTopic{Some More Text}
+ \StartText \input tufte \StopText
+ \StartText \input knuth \StopText
+ \StartText \input zapf \StopText
+ \StartText \input tufte \StopText
+ \StartText \input tufte \StopText
+ \StopTopic
+
+\StopPage
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-pre-30.mkiv b/tex/context/modules/mkiv/s-pre-30.mkiv
new file mode 100644
index 000000000..1be85d02b
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-30.mkiv
@@ -0,0 +1,257 @@
+%D \module
+%D [ file=s-pre-30,
+%D version=2006.04.25,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 30,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\usemodule[streams]
+
+\setuppapersize
+ [S6] [S6]
+
+\setupbodyfont
+ [12pt,tt]
+
+\definemeasure[bleed][6pt]
+
+\definecolor[maincolor-3][r=.5,g=.2,b=.2]
+\definecolor[maincolor-1][r=.2,g=.5,b=.2]
+\definecolor[maincolor-2][r=.2,g=.2,b=.5]
+
+\definecolor[pagecolor] [s=.5]
+\definecolor[resultcolor][s=1,t=.85,a=1]
+\definecolor[maincolor] [maincolor-3]
+
+\definecolorgroup
+ [maingroup]
+ [.5:.2:.2,
+ .2:.5:.2,
+ .2:.2:.5]
+
+\definecolorgroup
+ [resultgroup]
+ [1:.85:.85,
+ .85:1:.85,
+ .85:.85:1]
+
+\def\CurrentColor{1}
+
+\definecolor[maincolor] [maingroup:\CurrentColor]
+\definecolor[resultcolor][resultgroup:\CurrentColor]
+
+\def\NextColor{\ifnum\CurrentColor=3 \def\CurrentColor{1}\else\doglobal\increment\CurrentColor\fi}
+
+\setuplayout
+ [backspace=\measure{bleed},
+ topspace=30pt,
+ bottomdistance=\measure{bleed},
+ bottom=\dimexpr30pt-\measure{bleed}\relax,
+ header=0pt,
+ footer=0pt,
+ topdistance=\measure{bleed},
+ top=\dimexpr30pt-\measure{bleed}\relax,
+ width=middle,
+ height=middle]
+
+\setuptop
+ [before=\vfill,
+ after=\vfill,
+ strut=yes]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=\measure{bleed},
+ background=color,
+ backgroundcolor=maincolor]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=pagecolor]
+
+\setupcolors
+ [state=start,
+ textcolor=white]
+
+\setuphead
+ [chapter]
+ [style=\ttd]
+
+\setuphead
+ [section]
+ [style=\ttd]
+
+\defineviewerlayer
+ [result]
+ [state=stop]
+
+\definelayer
+ [result]
+
+\setuplayer
+ [result]
+ [width=\textwidth,
+ height=\textheight]
+
+\setupbackgrounds
+ [text]
+ [background={color,toggle,foreground,result}]
+
+\setupinteraction
+ [state=start,
+ click=no,
+ menu=on,
+ color=white,
+ contrastcolor=white,
+ closepageaction=HideLayer{result},
+ openpageaction=HideLayer{result}]
+
+% We add a dummy color switch so that each page has at least one
+% transparency; else acrobat will render the pages differently
+% bug in 6 and 7).
+
+\startinteractionmenu[bottom]
+% \color[resultcolor]{ }%
+ \hfill
+ \got [content] content \\
+ \got [previouspage] previous \\
+ \got [nextpage] next \\
+ \got [ToggleLayer{result}] result \\
+ \got [CloseDocument] close \\
+\stopinteractionmenu
+
+\setuphead
+ [section]
+ [placehead=no,
+ incrementnumber=list]
+
+\setuplist
+ [section]
+ [alternative=f]
+
+\defineoverlay
+ [toggle]
+ [\overlaybutton{ToggleLayer{result}}]
+
+\definestreamlayer
+ [resultstream]
+
+\startsetups streamlayer:resultstream:flush
+ \setlayer
+ [result]
+ [preset=middlebottom,
+ hoffset=\measure{bleed},
+% voffset=-\measure{bleed}]
+ voffset=\measure{bleed}]
+ {\startviewerlayer[result]%
+% \framed
+% [offset=overlay,
+% frame=off,
+% background=color,
+% backgroundoffset=1\dimexpr\measure{bleed}\relax,
+% backgroundcolor=maincolor]
+ {\framed
+ [offset=overlay,
+ frame=off,
+ foregroundcolor=maincolor,
+ background=color,
+ backgroundoffset=1\dimexpr\measure{bleed}\relax,
+ backgroundcolor=resultcolor]
+ {\tightlayer[\currentstreamlayer]}}
+ \stopviewerlayer}
+\stopsetups
+
+\startsetups show-definition
+ \subject{definition}
+ \typebuffer
+ \getbuffer
+ \page
+\stopsetups
+
+\startsetups show-result
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \getbuffer
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-usage
+ \subject{usage}
+ \typebuffer
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \getbuffer
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-usage-lines
+ \subject{usage}
+ \typebuffer
+ \startstreamlayer[resultstream]
+ \subject{result}
+ \startlines
+ \getbuffer
+ \stoplines
+ \stopstreamlayer
+ \placestreamlayer[resultstream]
+ \page
+\stopsetups
+
+\startsetups show-contents
+ \startcolumns[n=3]
+ \placelist[section][criterium=text]
+ \stopcolumns
+ \pagereference[content]
+ \page
+ \NextColor
+\stopsetups
+
+\def\TitlePage#1%
+ {\title{#1}
+ \setups{show-contents}}
+
+\def\StartSample#1%
+ {\starttext
+ \page
+ \section{#1}
+ \setuptoptexts[][\processedfile\enspace:\enspace\lowercase{#1}]}
+
+\def\StopSample
+ {\page
+ \setuptoptexts[][]
+ \stoptext
+ \NextColor}
+
+\endinput
+
+\usemodule[pre-30]
+
+% \TitlePage{Howling to the moon}
+
+\StartSample{Basics}
+
+\startbuffer
+\lua{a = 1.5 ; b = 1.8 ; c = a*b ; context(c) ;}
+
+\startlua
+ a = 1
+ b = 2
+ c = a*b
+ context(c)
+\stoplua
+\stopbuffer
+
+\setups{show-usage}
+
+\StopSample
diff --git a/tex/context/modules/mkiv/s-pre-60.mkiv b/tex/context/modules/mkiv/s-pre-60.mkiv
new file mode 100644
index 000000000..70f8978b0
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-60.mkiv
@@ -0,0 +1,212 @@
+%D \module
+%D [ file=s-pre-60,
+%D version=2004.03.15,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 60,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% use lua instead of global mess
+
+\unprotect
+
+\startmode[paper,print]
+ \let\StartSteps\relax
+ \let\StopSteps \relax
+ \let\FlushStep \relax
+ \let\ResetStep \relax
+ \let\StartBusy \relax
+ \let\StopBusy \relax
+ \endinput
+\stopmode
+
+\newcount\c_module_pre_steps_current
+\newcount\c_module_pre_steps_maximum
+\newcount\c_module_pre_steps_nesting_step
+\newcount\c_module_pre_steps_nesting_steps
+\newcount\c_module_pre_steps_nesting_busy
+
+\def\StepCounter {\the\c_module_pre_steps_current}
+\def\StepMaximum {\the\c_module_pre_steps_maximum}
+\def\StepLayer {step:\the\c_module_pre_steps_current}
+\def\NextStepLayer {step:\the\numexpr\c_module_pre_steps_current+\plusone\relax}
+\def\FirstStepLayer{step:1}
+
+\useJSscripts[stp]
+
+\startsetups[set-stepper]
+
+ \ifnum\getvariable{stepper}{nofsteps}>\c_module_pre_steps_maximum
+
+ \dostepwiserecurse {\numexpr\c_module_pre_steps_maximum+\plusone\relax} {\getvariable{stepper}{nofsteps}} {1} {
+ \doifnotmode{nosteps,nostep} {
+ \expanded{\defineviewerlayer[step:\recurselevel][state=stop,scope=global]}
+ }
+ }
+
+ \global\c_module_pre_steps_maximum\getvariable{stepper}{nofsteps}\relax
+
+ \fi
+
+\stopsetups
+
+\setvariables
+ [stepper]
+ [set=\setups{set-stepper},
+ nofsteps=50]
+
+\defineviewerlayer[step:busy][state=start]
+
+\definereference [SetupStepper] [JS(SetupStepper{step,\StepMaximum})]
+\definereference [ResetStepper] [JS(ResetStepper)]
+\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})]
+\definereference [InvokeStepper] [JS(InvokeStepper)]
+
+% todo: roll back blank
+
+\unexpanded\def\ResetStep
+ {\iftrialtypesetting\else
+ \global\c_module_pre_steps_current\zerocount
+ \fi}
+
+\unexpanded\def\NextStep
+ {\iftrialtypesetting\else
+ \global\advance\c_module_pre_steps_current\plusone
+ \fi}
+
+\unexpanded\def\PrevStep
+ {\iftrialtypesetting\else
+ \global\advance\c_module_pre_steps_current\minusone
+ \fi}
+
+\unexpanded\def\FlushStep
+ {\iftrialtypesetting\else
+ \StopStep
+ \NextStep
+ \StartStep
+ \fi}
+
+\unexpanded\def\StartStep
+ {\iftrialtypesetting\else
+ \global\advance\c_module_pre_steps_nesting_step\plusone
+ \ifcase\c_module_pre_steps_nesting_step\or
+ \startviewerlayer[\StepLayer]%
+ \fi
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\StopStep
+ {\removeunwantedspaces
+ \iftrialtypesetting\else
+ \ifcase\c_module_pre_steps_nesting_step\or
+ \stopviewerlayer
+ \fi
+ \global\advance\c_module_pre_steps_nesting_step\minusone
+ \fi}
+
+\unexpanded\def\StartSteps
+ {\iftrialtypesetting\else
+ \global\advance\c_module_pre_steps_nesting_steps\plusone
+ \ifcase\c_module_pre_steps_nesting_steps\or
+ \ResetStep
+ \NextStep
+ \StartStep
+ \fi
+ \fi}
+
+\unexpanded\def\StopSteps
+ {\iftrialtypesetting\else
+ \ifcase\c_module_pre_steps_nesting_steps\or
+ \StopStep
+ \PrevStep
+ \fi
+ \global\advance\c_module_pre_steps_nesting_steps\minusone
+ \fi}
+
+\unexpanded\def\StartBusy
+ {\iftrialtypesetting\else
+ \global\advance\c_module_pre_steps_nesting_busy\plusone
+ \ifcase\c_module_pre_steps_nesting_busy\or
+ \startviewerlayer[step:busy]
+ \fi
+ \fi
+ \ignorespaces}
+
+\unexpanded\def\StopBusy
+ {\removeunwantedspaces
+ \iftrialtypesetting\else
+ \ifcase\c_module_pre_steps_nesting_busy\or
+ \stopviewerlayer
+ \fi
+ \global\advance\c_module_pre_steps_nesting_busy\minusone
+ \fi}
+
+%D Handy:
+
+\unexpanded\def\StartLocalSteps
+ {\ResetStep}
+
+\unexpanded\def\StopLocalSteps
+ {}
+
+\unexpanded\def\StartLocalStep
+ {\NextStep
+ \StartStep}
+
+\unexpanded\def\StopLocalStep
+ {\StopStep}
+
+\appendtoks
+ \ResetStep
+\to \everyaftershipout
+
+\setupinteraction
+ [%openaction=SetupStepper,
+ closeaction=ResetStepper,
+ openpageaction=CheckStepper,
+ closepageaction=ResetStepper]
+
+\defineoverlay[invoke][\overlaybutton{InvokeStepper}]
+
+\setupbackgrounds
+ [text]
+ [background=invoke]
+
+% bonus
+
+\useMPlibrary[nav]
+
+\definepalet
+ [navplus]
+ [attach=interactioncolor,
+ comment=interactioncolor]
+
+\setupcomment
+ [symbol={comment-normal,comment-down},
+ textlayer=\StepLayer,
+ option=buffer,
+ height=\textheight,
+ width=\textwidth,
+ margin=0pt]
+
+\setupattachments
+ [symbol={attach-normal,attach-down},
+ textlayer=\StepLayer]
+
+%D used as (given some definitions):
+%D
+%D \starttyping
+%D \StartLocalSteps
+%D \startcombination[both]
+%D {\StartLocalStep\placestreamlayer[left]\StopLocalStep} {}
+%D {\StartLocalStep\placestreamlayer[right]\StopLocalStep} {}
+%D \stopcombination
+%D \StopLocalSteps
+%D \stoptyping
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-pre-69.mkiv b/tex/context/modules/mkiv/s-pre-69.mkiv
new file mode 100644
index 000000000..cc6af9ad3
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-69.mkiv
@@ -0,0 +1,336 @@
+%D \module
+%D [ file=s-pre-69,
+%D version=2010.04.28,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 69,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\setuppapersize[S6][S6]
+\setuppapersize[SM][SM]
+
+\usemodule
+ [abr-01,pre-60]
+
+\setupinteraction
+ [state=start,
+ contrastcolor=white,
+ color=white,
+ click=no]
+
+\setuplayout
+ [location=middle,
+ topspace=60pt,
+ bottomspace=80pt,
+ backspace=80pt,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupcolors
+ [textcolor=white]
+
+\setupbodyfont[euler]
+
+\definecolor[maincolor] [blue]
+\definecolor[extracolor][green]
+
+% \definecolor[maincolor] [red]
+% \definecolor[extracolor][blue]
+
+\startMPinitializations
+ if unknown MyColor[1] :
+ color MyColor[] ;
+ MyColor[1] := transparent(1,.25,\MPcolor{maincolor}) ;
+ MyColor[2] := transparent(1,.25,\MPcolor{extracolor}) ;
+
+ picture MySoFar ; MySoFar := nullpicture ;
+ path MyLastOne ; MyLastOne := origin -- cycle ;
+ color MyPageColor ; MyPageColor := MyColor[1] ;
+ path MyLeftSteps, MyRightSteps ;
+ boolean MyPageDone ; MyPageDone := false ;
+
+ vardef MySmallShape(expr parent) =
+ path p ; p := boundingbox parent ;
+ p := boundingbox parent ;
+ numeric w, h ; w := bbwidth(p) ; h := bbheight(p) ;
+ urcorner p shifted (-uniformdeviate w/4,0) --
+ lrcorner p shifted (0,uniformdeviate h/4) --
+ llcorner p shifted (uniformdeviate w/4,0) --
+ ulcorner p shifted (0,-uniformdeviate h/4) -- cycle
+ enddef ;
+
+ vardef MyShape(expr parent) =
+ path p ; p := boundingbox parent ;
+ if MyPageDone :
+ MyPageDone := false ;
+ urcorner p shifted (-EmWidth + -uniformdeviate CutSpace/2,0) --
+ lrcorner p shifted (0,EmWidth + uniformdeviate BottomSpace/2) --
+ llcorner p shifted (EmWidth + uniformdeviate BackSpace/2,0) --
+ ulcorner p shifted (0,-EmWidth + -uniformdeviate TopSpace/2) -- cycle
+ else :
+ MyPageDone := true ;
+ urcorner p shifted (0,-EmWidth + -uniformdeviate TopSpace/2) --
+ lrcorner p shifted (-EmWidth + -uniformdeviate CutSpace/2,0) --
+ llcorner p shifted (0,EmWidth + uniformdeviate BottomSpace/2) --
+ ulcorner p shifted (EmWidth + uniformdeviate BackSpace/2,0) -- cycle
+ fi
+ enddef ;
+
+ vardef MyMakeOne =
+ MyLastOne := MyShape(Page) ;
+ enddef ;
+
+ vardef MyAddOne =
+ addto MySoFar also image(fill MyLastOne withcolor MyPageColor ; ) ;
+ enddef ;
+
+ vardef MyDrawOne =
+ fill MyLastOne withcolor black ;
+ fill MyLastOne withcolor MyPageColor ;
+ enddef ;
+
+ vardef MyDrawPage =
+ draw MySoFar ;
+ enddef ;
+
+ vardef MySetSteps =
+ path l, r ; numeric s ; path ll[], rr[] ; path t ;
+ l := point 2 of MyLastOne -- point 3 of MyLastOne ;
+ r := point 0 of MyLastOne -- point 1 of MyLastOne ;
+ t := topboundary Field[Text][Text] rightenlarged TextWidth leftenlarged TextWidth ;
+ s := bbheight(Field[Text][Text])/LineHeight + 2 ;
+ t := t shifted (0,-TopSkip) ;
+ for i=1 upto s :
+ ll[i] := t intersectionpoint l ;
+ rr[i] := t intersectionpoint r ;
+ t := t shifted (0,-LineHeight) ;
+ endfor ;
+ MyLeftSteps := for i=1 upto s : ll[i] -- endfor cycle ;
+ MyRightSteps := for i=1 upto s : rr[i] -- endfor cycle ;
+ enddef ;
+
+ vardef MyDrawText(expr txt) =
+ pair a ; a := (point 1 of MyLastOne) - (point 2 of MyLastOne) ;
+ picture p ; p := txt ;
+ p := p
+ shifted (-EmWidth,EmWidth)
+ shifted ulcorner txt
+ shifted point 1 of MyLastOne ;
+ p := p rotatedaround(lrcorner p, radian * tan(ypart a/xpart a)) ;
+ setbounds p to origin -- cycle ;
+ draw p ;
+ enddef ;
+
+ vardef MyDrawTitle(expr txt) =
+ % pair a ; a := (point 2 of MyLastOne) - (point 3 of MyLastOne) ;
+ pair a ; a := (point 3 of MyLastOne) - (point 4 of MyLastOne) ;
+ picture p ;
+ if bbheight(txt) > bbwidth(txt) :
+ p := txt ysized(0.8*TextHeight) ;
+ else :
+ p := txt xsized(0.8*TextWidth) ;
+ fi ;
+ numeric d ; d := arclength(point 2 of MyLastOne -- point 3 of MyLastOne) - bbheight(p) ;
+ p := p
+ shifted (BackSpace,-d/2)
+ shifted -ulcorner p
+ shifted point 3 of MyLastOne ;
+ % p := p rotatedaround(ulcorner p, - radian * tan(xpart a/ypart a)) ;
+ % p := p rotatedaround(ulcorner p, radian * tan(ypart a/xpart a)) ;
+ setbounds p to origin -- cycle ;
+ draw p ;
+ enddef ;
+
+ vardef MyDrawSteps =
+ s := bbheight(Field[Text][Text])/LineHeight + 2 ;
+ for i=1 upto s :
+ draw ll[i] withpen pencircle scaled 1mm ;
+ draw rr[i] withpen pencircle scaled 1mm ;
+ draw ll[i] -- rr[i] ;
+ endfor ;
+ draw Field[Text][Text] ;
+ enddef ;
+
+ fi ;
+\stopMPinitializations
+
+\startuseMPgraphic{initialization}
+ StartPage ;
+ MySoFar := image(fill Page enlarged 12pt withcolor MyPageColor) ;
+ MyMakeOne ;
+ MySetSteps ;
+ StopPage ;
+\stopuseMPgraphic
+
+\appendtoks
+ \startnointerference
+ \useMPgraphic{initialization}
+ \stopnointerference
+\to \everystarttext
+
+\startuseMPgraphic{page}
+ StartPage ;
+ MyDrawPage ;
+ MyDrawOne ;
+ MySetSteps ;
+ MyDrawTitle(textext("\getvariable{document}{title}")) ;
+ MyDrawText(textext("\getvariable{document}{topic}")) ;
+ %
+ % we have multiple runs when we have text
+ %
+% MyDrawSteps ;
+% MyMakeOne ;
+% MySetSteps ;
+ StopPage ;
+\stopuseMPgraphic
+
+\appendtoks
+ \startnointerference
+ \startMPcode
+ MyAddOne ;
+ MyMakeOne ;
+ MySetSteps ;
+ \stopMPcode
+ \stopnointerference
+\to \everyshipout
+
+\defineoverlay[page][\useMPgraphic{page}]
+
+\startuseMPgraphic{symbol}
+ color cc ; cc := MyColor[2] ;
+ path p ; p := MySmallShape(unitsquare scaled (.6*LineHeight)) ;
+ fill p withcolor white ;
+ fill p withcolor cc ;
+\stopuseMPgraphic
+
+\definesymbol[mysymbol][\struttedbox{\useMPgraphic{symbol}}]
+
+\setupitemgroup[itemize][1][symbol=mysymbol]
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\startluacode
+ local texdimen = tex.dimen
+ function document.SetParShape()
+ local leftpath = metapost.getclippath("metafun","metafun","clip currentpicture to MyLeftSteps ;")
+ local rightpath = metapost.getclippath("metafun","metafun","clip currentpicture to MyRightSteps ;")
+ local shape = { }
+ for i=1,#leftpath do
+ local left = leftpath[i].x_coord
+ local right = rightpath[i].x_coord
+ local hsize = right - left - (texdimen.backspace + texdimen.cutspace)*number.dimenfactors.bp
+ shape[#shape+1] = string.format("%sbp %sbp",left,hsize)
+ end
+ -- print(table.serialize(shape))
+ -- context.parshape(string.format("%s %s ",#shape,table.concat(shape," ")))
+ context("\\parshape %s %s ",#shape,table.concat(shape," "))
+ end
+\stopluacode
+
+\nopenalties \dontcomplain
+
+\setupwhitespace[none]
+
+\def\StartText#1#2%
+ {\starttext
+ \setvariable{document}{title}{\framed[frame=off,offset=0pt,align=flushleft,foregroundstyle=\tfd\setupinterlinespace]{\begstrut#1\endstrut}}
+ \setvariable{document}{topic}{\tfb#2}
+ \startstandardmakeup
+ % dummy page
+ \stopstandardmakeup
+ \setvariable{document}{title}{}
+ \setvariable{document}{topic}{}}
+
+\def\StopText
+ {\stoptext}
+
+\def\StartItems#1%
+ {\setvariable{document}{topic}{\tfb#1}
+ \startstandardmakeup[top=,bottom=\vss]
+ \startelement[items][title={#1}]%
+ \ctxlua{document.SetParShape()}
+ \StartSteps}
+
+\def\StopItems
+ {\StopSteps
+ \stopelement
+ \stopstandardmakeup}
+
+\def\StartItem
+ {\dontleavehmode
+ \startelement[item]%
+ \llap{\symbol[mysymbol]\quad}% graphic
+ \ignorespaces}
+
+\def\StopItem
+ {\removeunwantedspaces
+ \nobreak
+ \crlf
+ \stopelement
+ \crlf
+ \FlushStep}
+
+\def\ShapeParagraph
+ {\ctxlua{document.SetParShape()}}
+
+% no parshape yet
+
+\def\StartParagraphs#1%
+ {\setvariable{document}{topic}{\tfb#1}
+ \startstandardmakeup[top=,bottom=\vss]
+ %\ctxlua{document.SetParShape()}
+ \startelement[paragraphs]%
+ \StartSteps}
+
+\def\StopParagraphs
+ {\StopSteps
+ \stopelement
+ \stopstandardmakeup}
+
+\def\StartParagraph
+ {\startelement[paragraph]}
+
+\def\StopParagraph
+ {\par
+ \stopelement
+ \FlushStep}
+
+% experiment .. likely to change
+
+\setelementexporttag[items] [nature][display]
+\setelementexporttag[item] [nature][mixed]
+\setelementexporttag[paragraphs][nature][display]
+\setelementexporttag[paragraph] [nature][mixed]
+
+\continueifinputfile{s-pre-69.mkiv}
+
+% finetuning: \StartText{\TEX\ and Reality\vskip2exClashing Mindsets?\vskip1ex}{Bacho\TEX, May 1, 2010}
+
+\StartText{Just\\A Demo}{Bacho\TEX, May 1, 2010}
+
+\StartItems{Quote from Tufte and Ward}
+ \StartItem
+ \input tufte
+ \StopItem
+ \StartItem
+ \input ward
+ \StopItem
+\StopItems
+
+% \dorecurse{20}{
+% \ctxlua{document.SetParShape()}
+% \input tufte
+% \page
+% }
+
+\StopText
+
diff --git a/tex/context/modules/mkiv/s-pre-70.mkiv b/tex/context/modules/mkiv/s-pre-70.mkiv
new file mode 100644
index 000000000..2c8bb2d26
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-70.mkiv
@@ -0,0 +1,176 @@
+%D \module
+%D [ file=s-pre-70,
+%D version=2008.04.15,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 70,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D At the cost of more runtime and a larger output file, we
+%D turn on randomization. The instances are cached in the
+%D MkIV cache, so successive runs use the same shapes.
+
+% \usemodule[punk] \usetypescript[punk] \setupbodyfont[punk,20pt]
+%
+% \EnableRandomPunk
+
+\setupbodyfont[punknova,20pt] % we now use the opentype variant
+
+%D We use the regular screen size paper and layout setup.
+
+\setuppapersize
+ [S6][S6]
+
+\setuplayout
+ [topspace=30pt,
+ backspace=30pt,
+ width=middle,
+ height=fit,
+ header=0pt,
+ footer=0pt,
+ bottomdistance=24pt,
+ bottom=30pt,
+ bottom=18pt,
+ top=0pt]
+
+\setupinterlinespace
+ [top=height,
+ line=1.25\bodyfontsize]
+
+\setupcolors
+ [state=start,
+ textcolor=white]
+
+\setupinteraction
+ [state=start,
+ %click=off,
+ menu=on]
+
+%D We predefine a few palets. Of course you can define more.
+
+\definecolor[punkblue] [r=.4,b=.8,g=.4]
+\definecolor[punkgreen] [r=.4,b=.4,g=.8]
+\definecolor[punkred] [r=.8,b=.4,g=.4]
+\definecolor[punkyellow][r=.6,g=.6,b=.2]
+
+\definepalet [punk-one] [textcolor=punkblue,pagecolor=punkgreen]
+\definepalet [punk-two] [textcolor=punkred,pagecolor=punkyellow]
+\definepalet [punk-three] [textcolor=punkblue,pagecolor=punkyellow]
+\definepalet [punk-one-reverse] [textcolor=punkgreen,pagecolor=punkblue]
+\definepalet [punk-two-reverse] [textcolor=punkyellow,pagecolor=punkred]
+\definepalet [punk-three-reverse] [textcolor=punkyellow,pagecolor=punkblue]
+
+\setuppalet[punk-one]
+
+%D We use a few backgrounds. The hyperlink that invokes the
+%D stepper is hooked into the text background.
+
+\definelayer
+ [page]
+ [width=\paperwidth,
+ height=\paperheight]
+
+\setupbackgrounds
+ [page]
+ [background={color,page},
+ backgroundcolor=pagecolor,
+ setups=pagestuff]
+
+\setupbackgrounds
+ [text]
+ [background={color,invoke},
+ backgroundoffset=12pt,
+ backgroundcolor=textcolor]
+
+%D We need different symbols for itemized lists.
+
+\definesymbol[1][\hbox{\lower1ex\hbox{*}}]
+\definesymbol[2][\endash]
+\definesymbol[3][\letterhash]
+\definesymbol[3][>]
+
+%D We don't want these reversed clicked areas in Acrobat.
+
+\setupinteraction
+ [click=no,
+ color=white, % pagecolor,
+ contrastcolor=white] % pagecolor,
+
+%D We define a rather simple navigational panel at the
+%D bottom
+
+\setupinteractionmenu
+ [bottom]
+ [color=white, % pagecolor,
+ contrastcolor=white, % pagecolor,
+ background=color,
+ backgroundcolor=textcolor,
+ frame=off,
+ height=24pt,
+ left=\hfill,
+ middle=\hskip12pt]
+
+\setupsubpagenumber
+ [state=start]
+
+\startinteractionmenu[bottom]
+ \starttxt
+ \interactionbar
+ [alternative=d,
+ symbol=yes,
+ color=white,
+ contrastcolor=textcolor]
+ \stoptxt
+ \hfilll
+ \startbut [previouspage] < < < \stopbut
+ \startbut [nextpage] > > > \stopbut
+\stopinteractionmenu
+
+%D Instead of the normal symbols we use more punky ones.
+
+\startsymbolset [punk]
+ \definesymbol[previous] [\string<\string<]
+ \definesymbol[somewhere] [\string^\string^]
+ \definesymbol[next] [\string>\string>]
+\stopsymbolset
+
+\setupinteraction[symbolset=punk]
+
+%D Because the font is rather large, we use less whitespace.
+
+\setuphead
+ [chapter]
+ [after={\blank[big]}]
+
+%D Run this file with the command: \type {context --mode=demo s-pre-70}
+%D in order to get an example.
+
+\continueifinputfile{s-pre-70.mkiv}
+
+\usemodule[pre-60] % use the stepper
+
+\starttext
+
+\title {Punk for dummies}
+
+\dorecurse{10} {
+
+ \title{Just a few dummy pages}
+
+ \StartSteps
+ \startitemize[packed]
+ \startitem bla \FlushStep \stopitem
+ \startitem bla bla \FlushStep \stopitem
+ \startitem bla bla bla \FlushStep \stopitem
+ \startitem bla bla bla bla \FlushStep \stopitem
+ \stopitemize
+ \StopSteps
+
+}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-pre-71.lua b/tex/context/modules/mkiv/s-pre-71.lua
new file mode 100644
index 000000000..bfa45a705
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-71.lua
@@ -0,0 +1,63 @@
+if not modules then modules = { } end modules ['steps'] = {
+ version = 1.001,
+ comment = "companion to steps.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+moduledata.steps = moduledata.steps or { }
+local steps = moduledata.steps
+
+local locations = {
+ 'lefttop',
+ 'middletop',
+ 'righttop',
+ 'middleleft',
+ 'middle',
+ 'middleright',
+ 'leftbottom',
+ 'middlebottom',
+ 'rightbottom',
+}
+
+local done, current, previous, n
+
+function steps.reset_locations()
+ done, current, previous, n = table.tohash(locations,false), 0, 0, 0
+end
+
+function steps.next_location(loc)
+ previous = current
+ n = n + 1
+ loc = loc and loc ~= "" and tonumber(loc)
+ while true do
+ current = loc or math.random(1,#locations)
+ if not done[current] then
+ done[current] = true
+ break
+ end
+ end
+end
+
+function steps.current_location()
+ context(locations[current] or "")
+end
+
+function steps.previous_location()
+ context(locations[previous] or "")
+end
+
+function steps.current_n()
+ context(current)
+end
+
+function steps.previous_n()
+ context(previous)
+end
+
+function steps.step()
+ context(n)
+end
+
+steps.reset_locations()
diff --git a/tex/context/modules/mkiv/s-pre-71.mkiv b/tex/context/modules/mkiv/s-pre-71.mkiv
new file mode 100644
index 000000000..38dae61df
--- /dev/null
+++ b/tex/context/modules/mkiv/s-pre-71.mkiv
@@ -0,0 +1,170 @@
+% engine=luatex
+
+%D \module
+%D [ file=s-pre-71,
+%D version=2008.08.05,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment 71,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D I might improve this module so consider it experimental.
+
+% \enablemode[numbers]
+% \enablemode[paper]
+
+\usemodule[pre-60,abr-02]
+
+\registerctxluafile{s-pre-71}{}
+
+\setupinteraction[state=start,click=off]
+
+\definepapersize[wide][width=900pt,height=600pt]
+
+\setuppapersize[wide][wide]
+
+\setuplayout[page]
+
+% \setupbodyfont[15pt]
+
+\usetypescriptfile[type-hgz]
+\usetypescript[palatino-informal]
+\setupbodyfont[palatino-informal,15pt]
+
+\setupsorting[logo][style=]
+
+\startnotmode[paper]
+ \setupbackgrounds[page][background=color,backgroundcolor=black]
+\stopnotmode
+
+\TransparencyHack
+
+\definelayer[page][width=\paperwidth,height=\paperheight]
+
+\definecolor[TopicColor-1][r=.3,g=.4,b=.5]
+\definecolor[TopicColor-2][r=.3,g=.5,b=.4]
+\definecolor[TopicColor-3][r=.4,g=.3,b=.5]
+\definecolor[TopicColor-4][r=.4,g=.5,b=.3]
+\definecolor[TopicColor-5][r=.5,g=.3,b=.4]
+\definecolor[TopicColor-6][r=.5,g=.4,b=.3]
+\definecolor[TopicColor-7][r=.35,g=.35,b=.6]
+\definecolor[TopicColor-8][r=.6,g=.35,b=.35]
+\definecolor[TopicColor-9][r=.35,g=.6,b=.35]
+
+\definecolor[TopicColor-0][t=.5,a=1,s=.5]
+\definecolor[TopicColor] [s=1]
+
+\setupcolors[state=start]
+\setupcolors[textcolor=TopicColor]
+
+\def\StartTopics
+ {\startstandardmakeup
+ \ctxlua{moduledata.steps.reset_locations()}
+ \doifnotmode{paper}{\StartLocalSteps}}
+
+\def\StopTopics
+ {\doifnotmode{paper}{\StopLocalSteps}
+ \flushlayer[page]
+ \stopstandardmakeup}
+
+\def\StartTopic
+ {\dosingleempty\doStartTopic}
+
+\def\doStartTopic[#1]%
+ {\doifnotmode{paper}{\NextStep}
+ \ctxlua{moduledata.steps.next_location("#1")}
+ \startnotmode[paper]
+ \doifnothing{#1}
+ {\ifcase\ctxlua{moduledata.steps.previous_n()}\else
+ \setlayer
+ [page]
+ [preset=\ctxlua{moduledata.steps.previous_location()}]
+ \bgroup
+ \doifnotmode{paper}{\startviewerlayer[\StepLayer]}%
+ \framed
+ [offset=20pt,
+ strut=no,
+ align=normal,
+ frame=off,
+ height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ background=color,
+ backgroundcolor=TopicColor-0]
+ {}%
+ \doifnotmode{paper}{\stopviewerlayer}%
+ \egroup
+ \fi}
+ \stopnotmode
+ \setlayer
+ [page]
+ [preset=\ctxlua{moduledata.steps.current_location()}]
+ \bgroup
+ \doifnotmode{paper}{\startviewerlayer[\StepLayer]}%
+ \framed
+ [offset=20pt,
+ strut=no,
+ align=\expdoifelse{#1}{}{normal}{middle,lohi},
+ align=\expdoifelse{#1}{}{flushleft,verytolerant}{middle,lohi},
+ frame=off,
+ height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ background=color,
+ backgroundcolor=TopicColor-\ctxlua{moduledata.steps.current_n()}]
+ \bgroup
+ \ignorespaces}
+
+\def\StopTopic
+ {\removeunwantedspaces
+ \egroup
+ \doifnotmode{paper}{\stopviewerlayer}%
+ \egroup
+ \startmode[numbers]
+ \setlayerframed
+ [page]
+ [preset=\ctxlua{moduledata.steps.current_location()}]
+ [height=\dimexpr\paperheight/3\relax,
+ width=\dimexpr\paperwidth/3\relax,
+ frame=off,
+ foregroundstyle=\bfa,
+ align={flushright,low}]
+ {\doifnotmode{paper}{\startviewerlayer[\StepLayer]}%
+ \ctxlua{moduledata.steps.step()}\kern\strutdepth
+ \doifnotmode{paper}{\stopviewerlayer}}
+ \stopmode}
+
+\logo [METAPOST] {MetaPost}
+
+\definefont[TitleFont][SansBold at 60pt]
+\definefont[TempFont] [SansBold at 12pt]
+
+\let\StartText\starttext
+\let\StopText \stoptext
+
+\continueifinputfile{s-pre-71.mkiv}
+
+\starttext
+
+\StartTopics
+ \StartTopic[1] A \StopTopic
+ \StartTopic[5] B \StopTopic
+ \StartTopic[9] C \StopTopic
+\StopTopics
+
+\StartTopics
+ \StartTopic A \StopTopic
+ \StartTopic B \StopTopic
+ \StartTopic C \StopTopic
+ \StartTopic D \StopTopic
+ \StartTopic E \StopTopic
+ \StartTopic F \StopTopic
+ \StartTopic G \StopTopic
+ \StartTopic H \StopTopic
+ \StartTopic I \StopTopic
+\StopTopics
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-present-tiles.mkiv b/tex/context/modules/mkiv/s-present-tiles.mkiv
new file mode 100644
index 000000000..b68a34ef4
--- /dev/null
+++ b/tex/context/modules/mkiv/s-present-tiles.mkiv
@@ -0,0 +1,318 @@
+%D \module
+%D [ file=s-present-tiles, % was s-pre-41
+%D version=2013.03.24,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Presentation Environment Tiles,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The Bacho\TeX\ 2013 style.
+
+\setupbodyfont[pagella,14.4pt]
+
+\setuppapersize[S6][S6]
+
+\definecolor[primarycolor] [.50(darkblue,darkgreen)]
+\definecolor[secondarycolor][.25(darkblue,darkyellow)]
+\definecolor[mixedcolor] [s=.35]
+
+\setupcolors
+ [textcolor=white]
+
+\setupalign
+ [flushleft,nothyphenated]
+
+\definemeasure[layoutunit][\dimexpr\paperheight/25]
+
+\setuplayout
+ [backspace=\measured{layoutunit},
+ topspace=\measured{layoutunit},
+ width=middle,
+ height=middle,
+ header=0pt,
+ footer=0pt]
+
+\definelayout
+ [content]
+ [backspace=.5\measured{layoutunit},
+ topspace=.5\measured{layoutunit}]
+
+\definemeasure [topiclistwidth] [
+ (\textwidth+\backspace)/
+ \ifcase\numexpr\structurelistsize\relax 1 % 0
+ \or1\or1\or1\or2\or1\or3\or3\or3\or3 % 1 - 9
+ \or3\or3\or3\or3\or3\or3\or4 % 10 - 16
+ \or4\or4\or4\or4\or % 17 - 20
+ \else5 % 21 - 25
+ \fi
+ -\backspace
+]
+
+\definemeasure [topiclistheight] [
+ (\textheight+\topspace)/
+ \ifcase\numexpr\structurelistsize\relax 1 % 0
+ \or1\or2\or3\or2\or5\or2\or3\or3\or3 % 1 - 9
+ \or4\or4\or4\or4\or4\or4\or4 % 10 - 16
+ \or5\or5\or5\or5\or5 % 17 - 20
+ \else5 % 21 - 25
+ \fi
+ -\topspace
+]
+
+\definemeasure [topiclistfontsize] [
+ \ifcase\numexpr\structurelistsize\relax 2.5 % 0
+ \or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4\or1.4 % 1 - 9
+ \or1.3\or1.3\or1.3\or1.3\or1.3\or1.3\or1.3 % 10 - 16
+ \or1.2\or1.2\or1.2\or1.2\or1.2 % 17 - 20
+ \else1 % 21 - 25
+ \fi
+ \bodyfontsize
+]
+
+\definemeasure [topiclistfont] [\measured{topiclistfontsize}]
+\definemeasure [topictitlefont] [1.2\measured{layoutunit}]
+\definemeasure [titlepagefont] [2\measured{layoutunit}]
+
+\predefinefont[MyTopicTitleFont][SerifBold*default at \measure{topictitlefont}]
+\predefinefont[MyTopicListFont] [SerifBold*default at \measure{topiclistfont}]
+
+\defineframed
+ [topiclistentry]
+ [width=\measure{topiclistwidth},
+ height=\measure{topiclistheight},
+ background=color,
+ frame=off,
+ foregroundstyle=MyTopicListFont,
+ backgroundcolor=primarycolor,
+ foregroundcolor=white]
+
+\setupwhitespace
+ [big]
+
+\setupblank
+ [big]
+
+\setupinteraction
+ [state=start,
+ color=,
+ contrastcolor=,
+ click=off]
+
+\definemakeup
+ [topic]
+ [standard]
+ [top=,bottom=]
+
+\definemakeup
+ [content]
+ [standard]
+ [top=,bottom=]
+
+\startsetups[topic:start]
+ \starttopicmakeup
+\stopsetups
+
+\startsetups[topic:stop]
+ \vfill
+ \stoptopicmakeup
+\stopsetups
+
+\definehead
+ [topic]
+ [chapter]
+ [before=,
+ style=MyTopicTitleFont,
+ page=,
+ number=off,
+ interaction=list,
+ beforesection=\directsetup{topic:start},
+ aftersection=\directsetup{topic:stop}]
+
+\setuplist
+ [topic]
+ [alternative=topic,
+ interaction=all]
+
+\definelistalternative
+ [topic]
+ [alternative=horizontal,
+ renderingsetup=topic:list]
+
+\startsetups[topic:list]
+ \dontleavehmode
+ \startcurrentlistentrywrapper
+ \topiclistentry{\currentlistentrytitle}
+ \stopcurrentlistentrywrapper
+ \blankspace
+\stopsetups
+
+\defineoverlay[nextpage][\overlaybutton{nextpage}]
+\defineoverlay[prevpage][\overlaybutton{prevpage}]
+\defineoverlay[menupage][\overlaybutton{menupage}]
+\defineoverlay[homepage][\overlaybutton{homepage}]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=.5\measured{layoutunit}]
+
+% begin of buttons
+
+\defineframed
+ [bb]
+ [width=\dimexpr\overlaywidth/10,
+ height=\dimexpr\overlayheight/10,
+ background=color,
+ foregroundstyle=\bfa,
+ frame=off]
+
+\defineframed[nb] [bb] [empty=yes]
+\defineframed[rb] [bb] [backgroundcolor=white,foregroundcolor=secondarycolor]
+\defineframed[db] [bb] [backgroundcolor=mixedcolor,foregroundcolor=white]
+
+\definepushbutton [prev]
+\definepushbutton [next]
+\definepushbutton [menu]
+\definepushbutton [home]
+
+\definepushsymbol [prev] [n] [\nb{prev}]
+\definepushsymbol [prev] [r] [\rb{prev}]
+\definepushsymbol [prev] [d] [\db{prev}]
+
+\definepushsymbol [next] [n] [\nb{next}]
+\definepushsymbol [next] [r] [\rb{next}]
+\definepushsymbol [next] [d] [\db{next}]
+
+\definepushsymbol [menu] [n] [\nb{menu}]
+\definepushsymbol [menu] [r] [\rb{menu}]
+\definepushsymbol [menu] [d] [\db{menu}]
+
+\definepushsymbol [home] [n] [\nb{home}]
+\definepushsymbol [home] [r] [\rb{home}]
+\definepushsymbol [home] [d] [\db{home}]
+
+\definelayer
+ [buttons]
+ [width=\dimexpr\textwidth+\measured{layoutunit}\relax,
+ height=\dimexpr\textheight+\measured{layoutunit}\relax] % a setups
+
+\startsetups [document:buttons]
+
+ \setlayer
+ [buttons]
+ [preset=leftbottom,offset=-.25\measured{layoutunit}]
+ {\pushbutton[prev][previouspage]}
+
+ \setlayer
+ [buttons]
+ [preset=rightbottom,offset=-.25\measured{layoutunit}]
+ {\pushbutton[next][nextpage]}
+
+ \setlayer
+ [buttons]
+ [preset=lefttop,offset=-.25\measured{layoutunit}]
+ {\pushbutton[home][homepage]}
+
+ \setlayer
+ [buttons]
+ [preset=righttop,offset=-.25\measured{layoutunit}]
+ {\pushbutton[menu][menupage]}
+
+\stopsetups
+
+\defineoverlay[setbuttons][\directsetup{document:buttons}]
+
+% end of buttons
+
+\defineframed
+ [conclusion]
+ [location=low,
+ width=max,
+ align={flushleft,lohi},
+ background=color,
+ backgroundcolor=white,
+ foregroundcolor=secondarycolor]
+
+\startsetups [document:titlepage]
+
+ \definebodyfontenvironment
+ [\measure{titlepagefont}]
+
+ \setupbackgrounds
+ [page]
+ [background={color,menupage},
+ backgroundcolor=secondarycolor]
+
+ \setupbackgrounds
+ [text]
+ [background={color,menupage},
+ backgroundcolor=secondarycolor]
+
+ \starttopicmakeup[reference=homepage]
+
+ \switchtobodyfont[\measure{titlepagefont}]
+
+ \let\\=\crlf
+
+ \startalignment[flushleft]
+ \bf
+ \setupinterlinespace
+ \begstrut\getvariable{document}{title}\endstrut\par
+ \stopalignment
+
+ \vfill
+
+ \startalignment[flushright]
+ \bf
+ \setupinterlinespace
+ \begstrut\getvariable{document}{subtitle}\endstrut\par
+ \stopalignment
+
+ \stoptopicmakeup
+
+ \setupbackgrounds
+ [page]
+ [background={color,homepage},
+ backgroundcolor=secondarycolor]
+
+ \setupbackgrounds
+ [text]
+ [background={color,menupage},
+ backgroundcolor=secondarycolor]
+
+ \startcontentmakeup[reference=menupage]
+
+ \setupalign[tolerant,stretch,paragraph]
+ \flexiblebaselines
+ \placelist[topic][criterium=text]
+
+ \stopcontentmakeup
+
+ \setupbackgrounds
+ [page]
+ % [background={color,menupage},
+ [background={color,invoke},
+ backgroundcolor=primarycolor]
+
+ \setupbackgrounds
+ [text]
+ % [background={color,nextpage,setbuttons,buttons},
+ [background={color,setbuttons,buttons},
+ backgroundcolor=secondarycolor]
+
+\stopsetups
+
+\setupdocument
+ [before=\directsetup{document:titlepage}]
+
+\continueifinputfile{s-present-tiles.mkiv}
+
+\startdocument[title=Whatever We\\Want Here,subtitle=Whatever We\\Want There]
+
+ \dorecurse{12}{\starttopic[title=Topic #1]\input tufte \stoptopic}
+
+\stopdocument
diff --git a/tex/context/modules/mkiv/s-references-show.mkiv b/tex/context/modules/mkiv/s-references-show.mkiv
new file mode 100644
index 000000000..72cccce54
--- /dev/null
+++ b/tex/context/modules/mkiv/s-references-show.mkiv
@@ -0,0 +1,132 @@
+%D \module
+%D [ file=s-references-show.mkiv,
+%D version=2015.04.13,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Reference Checking,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[references-show]
+
+\unprotect
+
+% \enabletrackers[nodes.references,nodes.destinations] % also shows areas
+
+\enabletrackers[nodes.references.show,nodes.destinations.show]
+
+\enablehiddenbackground % trick
+
+\edef\hiddenbackgroundlist{\hiddenbackgroundlist,trace-references}
+
+\defineoverlay
+ [trace-references]
+ [\directsetup{trace:references:onpage}]
+
+\startluacode
+ local pagelist = structures.references.tracedpages
+
+ function commands.getreferencesonpage(n)
+ n = tonumber(n)
+ if n then
+ local pagedata = pagelist[n]
+ if pagedata then
+ context("%s references",#pagedata)
+ context.blank()
+ for i=1,#pagedata do
+ local details = pagedata[i]
+ local prefix = details[1]
+ local reference = details[2]
+ -- local internal = details[3]
+ -- context("%04i = %s : %s",internal,prefix == "" and "-" or prefix,reference)
+ context("%s : %s",prefix == "" and "-" or prefix,reference)
+ context.par()
+ end
+ else
+ context("no references")
+ end
+ else
+ context("no valid page")
+ end
+ end
+
+\stopluacode
+
+\definecolor
+ [trace:references:onpage]
+ [b=.5,a=1,t=.25]
+
+\defineframed
+ [trace:references:onpage]
+ [\c!offset=2\exheight,
+ %\c!foregroundstyle=\infofont,
+ \c!frame=\v!off,
+ \c!background=\v!color,
+ \c!backgroundcolor=trace:references:onpage,
+ \c!align=\v!normal]
+
+\startsetups trace:references:onpage
+ \vbox to \vsize \bgroup
+ \infofont
+ \vskip\dimexpr-\topspace-\headerheight+2\exheight\relax
+ \hbox to \hsize \bgroup
+ \doifoddpageelse\hss{\hskip\dimexpr-\cutspace+2\exheight\relax}%
+ \directlocalframed [
+ trace:references:onpage
+ ] {
+ \ctxcommand{getreferencesonpage(\the\realpageno)}
+ }
+ \doifoddpageelse{\hskip\dimexpr-\cutspace+2\exheight\relax}\hss
+ \egroup
+ \vss
+ \egroup
+\stopsetups
+
+\protect
+
+\continueifinputfile{s-references-show.mkiv}
+
+\usemodule[art-01]
+
+\setupinteraction
+ [state=start]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\starttext
+
+\title {Contents}
+
+\placelist[chapter]
+
+\setupreferenceprefix[zero]
+
+\chapter[crap]{foo}
+
+\setupreferenceprefix[one]
+
+test \pagereference[whatever]
+
+\dorecurse{5}{
+ \placefigure
+ [here][bar 1.#1]
+ {xx}{\framed{xx #1}}
+}
+
+\setupreferenceprefix[two]
+
+\dorecurse{5}{
+ \placefigure
+ [here][bar 2.#1]
+ {xx}{\framed{xx #1}}
+}
+
+\in{checked}[bar 1.1]
+\in{checked}[bar 2.1]
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-reg-01.mkiv b/tex/context/modules/mkiv/s-reg-01.mkiv
new file mode 100644
index 000000000..36434c30c
--- /dev/null
+++ b/tex/context/modules/mkiv/s-reg-01.mkiv
@@ -0,0 +1,60 @@
+%D \module
+%D [ file=s-reg-01,
+%D version=2005.04.25,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Extra Regime Support,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D \macros
+%D {showregime}
+%D
+%D This code is moved from the kernel to here. (We could make it
+%D auto-loadable).
+
+\startluacode
+--[[ldx--
+<p>The following code is rather <l n='context'/> specific.</p>
+--ldx]]--
+
+function regimes.show(regime)
+ regime = regimes.synonyms[regime] or regime
+ local r = regimes.data[regime]
+ if r then
+ local chardata = characters.data
+ context.starttabulate { "|rT|T|rT|lT|lT|lT|" }
+ for k, v in ipairs(r) do
+ local chr = chardata[v]
+ if chr then
+ context.NC() context(k)
+ context.NC() context.getvalue(chr.contextname])
+ context.NC() context("%U+05X",v)
+ context.NC() context(chr.contextname)
+ context.NC() context(chr.category)
+ context.NC() context(chr.description)
+ context.NC() context.NR()
+ else
+ -- can't happen
+ end
+ end
+ context.stoptabulate()
+ else
+ context("unknown regime %s",regime)
+ end
+end
+\stopluacode
+
+\unprotect
+
+\def\showregime
+ {\dosingleempty\doshowregime}
+
+\def\doshowregime[#1]%
+ {\ctxlua{regimes.show("#1")}}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-set-31.mkiv b/tex/context/modules/mkiv/s-set-31.mkiv
new file mode 100644
index 000000000..53037a78d
--- /dev/null
+++ b/tex/context/modules/mkiv/s-set-31.mkiv
@@ -0,0 +1,118 @@
+% show missing translations
+
+\startluacode
+function interfaces.show_missing(whatinterfaces)
+ whatinterfaces = whatinterfaces or interfaces.interfaces
+ local list = dofile(resolvers.find_file("mult-def.lua"))
+ local NC, NR, HL = context.NC, context.NR, context.HL
+ for k,v in table.sortedhash(list) do
+ context.title(k)
+ context.starttabulate { string.rep("|",#whatinterfaces+1) }
+ for i=1,#whatinterfaces do
+ NC()
+ context(whatinterfaces[i])
+ end
+ NC() NR() HL()
+ for kk, vv in next, v do
+ if not string.find(kk,"subsub") then
+ local okay = true
+ for i=1,#whatinterfaces do
+ local int = whatinterfaces[i]
+ local str = vv[int]
+ if not str or (int ~= "en" and str == vv.en) then
+ okay = false
+ break
+ end
+ end
+ if not okay then
+ for i=1,#whatinterfaces do
+ local int = whatinterfaces[i]
+ local str = vv[int]
+ context.NC()
+ if not str then
+ -- nothing
+ elseif int == "en" then
+ context.color( { "darkgreen" }, str )
+ elseif str == vv.en then
+ context.color( { "darkred" }, str )
+ elseif int == "pe" then
+ context("\\righttoleft " .. str)
+ else
+ context(str)
+ end
+ end
+ NC() NR()
+ end
+ end
+ end
+ context.stoptabulate()
+ end
+end
+
+function interfaces.show_missing_messages(whatinterfaces)
+ whatinterfaces = whatinterfaces or interfaces.interfaces
+ local list = dofile(resolvers.find_file("mult-mes.lua"))
+ local NC, NR, HL = context.NC, context.NR, context.HL
+ for k,v in table.sortedhash(list) do
+ context.title("message: " .. k)
+ context.starttabulate { "|l|" .. string.rep("pl|",#whatinterfaces) }
+ NC()
+ for i=1,#whatinterfaces do
+ NC()
+ context(whatinterfaces[i])
+ end
+ NC() NR() HL()
+ local sorted = table.sortedkeys(v)
+ for i=1,#sorted do
+ local kk = sorted[i]
+ local vv = v[kk]
+ if kk ~= "files" then
+ local okay = true
+ for i=1,#whatinterfaces do
+ local int = whatinterfaces[i]
+ local str = vv[int]
+ if not str or (int ~= "en" and str == vv.en) then
+ okay = false
+ break
+ end
+ end
+ if not okay then
+ context.NC()
+ context(kk)
+ for i=1,#whatinterfaces do
+ local int = whatinterfaces[i]
+ local str = vv[int]
+ NC()
+ if not str then
+ -- nothing
+ elseif int == "en" then
+ context.color( { "darkgreen" }, str )
+ elseif str == vv.en then
+ context.color( { "darkred" }, str )
+ elseif int == "pe" then
+ context("\\righttoleft " .. str)
+ else
+ context(str)
+ end
+ end
+ NC() NR()
+ end
+ end
+ end
+ context.stoptabulate()
+ end
+end
+\stopluacode
+
+\starttext
+
+\setupbodyfont[dejavu,7pt,tt]
+\setuppapersize[A4,landscape][A4,landscape]
+\setuplayout[backspace=.5cm,width=middle,topspace=.5cm,height=middle,header=1cm,footer=0cm]
+
+\startluacode
+ interfaces.show_missing() -- { "en","nl" }
+ interfaces.show_missing_messages() -- { "en","nl" }
+\stopluacode
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-sql-tables.lua b/tex/context/modules/mkiv/s-sql-tables.lua
new file mode 100644
index 000000000..434103541
--- /dev/null
+++ b/tex/context/modules/mkiv/s-sql-tables.lua
@@ -0,0 +1,152 @@
+if not modules then modules = { } end modules ['s-languages-counters'] = {
+ version = 1.001,
+ comment = "companion to s-languages-counters.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+require("util-tpl")
+require("util-sql")
+require("util-sql-tracers")
+
+moduledata = moduledata or { }
+moduledata.sql = moduledata.sql or { }
+moduledata.sql.tables = moduledata.sql.tables or { }
+
+local context = context
+
+function moduledata.sql.showfields(specification) -- not that sql specific
+ local data = specification.data
+ if data and #data > 0 then
+ local keys = specification.order or table.sortedkeys(data[1])
+ local align = specification.align
+ local template = "|"
+ if type(align) == "table" then
+ for i=1,#keys do
+ template = template .. (align[keys[i]] or "c") .. "|"
+ end
+ else
+ template = template .. string.rep((align or "c").. "|",#keys)
+ end
+ context.starttabulate { template }
+ context.NC()
+ for i=1,#keys do
+ context(keys[i])
+ context.NC()
+ end
+ context.NR()
+ context.HL()
+ for i=specification.first or 1,specification.last or #data do
+ local d = data[i]
+ context.NC()
+ for i=1,#keys do
+ context(d[keys[i]])
+ context.NC()
+ end
+ context.NR()
+ end
+ context.stoptabulate()
+ end
+end
+
+function moduledata.sql.validpresets(presets)
+ local okay = true
+ if presets.database == "" then
+ context("No database given.")
+ context.blank()
+ okay = false
+ end
+ if presets.password == "" then
+ context("No password given")
+ context.blank()
+ okay = false
+ end
+ return okay
+end
+
+function moduledata.sql.tables.showdefined(presets) -- key=value string | { presets = "name" } | { presets }
+
+ if type(presets) == "string" then
+ local specification = interfaces.checkedspecification(presets)
+ if specification.presets then
+ presets = table.load(specification.presets) or { }
+ end
+ end
+
+ if type(presets.presets) == "string" then
+ presets = table.load(presets.presets) or { }
+ end
+
+ if not moduledata.sql.validpresets(presets) then
+ return
+ end
+
+ local sql_tables = utilities.sql.tracers.gettables(presets)
+
+ context.starttitle { title = presets.database }
+
+ for name, fields in table.sortedhash(sql_tables) do
+
+ context.startsubject { title = name }
+
+ context.starttabulate { format = "|l|l|l|l|l|p|" }
+ context.FL()
+ context.NC() context.bold("field")
+ context.NC() context.bold("type")
+ context.NC() context.bold("default")
+ context.NC() context.bold("null")
+ context.NC() context.bold("key")
+ context.NC() context.bold("extra")
+ context.NC() context.NR()
+ context.TL()
+ for i=1,#fields do
+ local field = fields[i]
+ context.NC() context(field.field)
+ context.NC() context(field.type)
+ context.NC() context(field.default)
+ context.NC() context(field.null)
+ context.NC() context(field.key)
+ context.NC() context(field.extra)
+ context.NC() context.NR()
+ end
+ context.LL()
+ context.stoptabulate()
+
+ context.stopsubject()
+ end
+
+ context.stoptitle()
+
+end
+
+function moduledata.sql.tables.showconstants(list)
+
+ context.starttitle { title = "Constants" }
+
+ for name, fields in table.sortedhash(list) do
+
+ if type(fields) == "table" and #fields > 0 then
+
+ context.startsubject { title = name }
+
+ context.starttabulate { format = "|l|l|" }
+ for i=0,#fields do
+ local field = fields[i]
+ if field then
+ context.NC() context(i)
+ context.NC() context(field)
+ context.NC() context.NR()
+ end
+ end
+ context.stoptabulate()
+
+ context.stopsubject()
+
+ end
+
+ end
+
+ context.stoptitle()
+
+end
diff --git a/tex/context/modules/mkiv/s-sql-tables.mkiv b/tex/context/modules/mkiv/s-sql-tables.mkiv
new file mode 100644
index 000000000..4c8bcddac
--- /dev/null
+++ b/tex/context/modules/mkiv/s-sql-tables.mkiv
@@ -0,0 +1,30 @@
+%D \module
+%D [ file=s-sql-tables,
+%D version=2012.07.12,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=SQL,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[sql-tables]
+
+\registerctxluafile{s-sql-tables}{}
+
+\doifsomething {\currentmoduleparameter{method}}{
+ \ctxlua{utilities.sql.setmethod("\currentmoduleparameter{method}")}
+}
+
+\doifsomething {\currentmoduleparameter{server}} {
+ \ctxlua{utilities.sql.setserver("\currentmoduleparameter{server}")}
+}
+
+\installmodulecommandluasingle \showdefinedsqltables {moduledata.sql.tables.showdefined}
+
+\stopmodule
+
+
diff --git a/tex/context/modules/mkiv/s-structure-sections.mkiv b/tex/context/modules/mkiv/s-structure-sections.mkiv
new file mode 100644
index 000000000..daaab5abc
--- /dev/null
+++ b/tex/context/modules/mkiv/s-structure-sections.mkiv
@@ -0,0 +1,80 @@
+%D \module
+%D [ file=s-structure-sections,
+%D version=2015.02.02,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Structure Sections,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\startluacode
+ local context = context
+ local ctx_NC, ctx_NR = context.NC, context.NR
+ local ctx_bold = context.bold
+
+ structures.tracers = structures.tracers or { }
+
+ function structures.tracers.showsections()
+
+ local list = structures.sections.registered
+ local keys = table.keys(list)
+ table.sort(keys,function(a,b)
+ local la, lb = list[a].level, list[b].level
+ if la == lb then
+ return a < b
+ else
+ return la < lb
+ end
+ end)
+ context.start()
+ context.switchtobodyfont { "tt" }
+ context.starttabulate { "||c||||" }
+ context.FL()
+ ctx_NC() ctx_bold("name")
+ ctx_NC() ctx_bold("level")
+ ctx_NC() ctx_bold("parent")
+ ctx_NC() ctx_bold("section")
+ ctx_NC() ctx_bold("coupling")
+ ctx_NC() context.NR()
+ context.ML()
+ for i=1,#keys do
+ local k = keys[i]
+ local v = list[k]
+ ctx_NC() ctx_bold(k)
+ ctx_NC() context(v.level)
+ ctx_NC() context(v.parent)
+ ctx_NC() context(v.section)
+ ctx_NC() context(v.coupling)
+ ctx_NC() context.NR()
+ end
+ context.LL()
+ context.stoptabulate()
+ context.stop()
+
+ end
+\stopluacode
+
+
+\starttexdefinition showstructuresections
+
+ % no settings yet
+
+ \ctxlua{structures.tracers.showsections()}
+
+\stoptexdefinition
+
+\protect
+
+\continueifinputfile{s-structure-sections.mkiv}
+
+\starttext
+
+ \showstructuresections
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-syntax.mkiv b/tex/context/modules/mkiv/s-syntax.mkiv
new file mode 100644
index 000000000..96312f771
--- /dev/null
+++ b/tex/context/modules/mkiv/s-syntax.mkiv
@@ -0,0 +1,96 @@
+%D \module
+%D [ file=s-syntax, % was: s-syn-01,
+%D version=0000.00.00,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Preliminary Syntax Stuff,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is needed for the \METAFUN\ manual: quite old code that I would do
+%D differently nowadays.
+
+\unprotect
+
+\unexpanded\def\module_syntax_Indent #1{\ifvmode\noindent\hbox to 2em{\hss#1}\else#1\fi}
+\unexpanded\def\module_syntax_Sugar #1{\removeunwantedspaces\kern.25em{#1}\kern.25em\ignorespaces}
+\unexpanded\def\module_syntax_Something #1{\Sugar{\mathematics{\langle\hbox{#1}\rangle}}}
+\unexpanded\def\module_syntax_Lbrace {\Sugar{\tttf\leftargument}}
+\unexpanded\def\module_syntax_Rbrace {\Sugar{\tttf\rightargument}}
+\unexpanded\def\module_syntax_Lparent {\Sugar{\tttf(}}
+\unexpanded\def\module_syntax_Rparent {\Sugar{\tttf)}}
+\unexpanded\def\module_syntax_Lbracket {\Sugar{\tttf[}}
+\unexpanded\def\module_syntax_Rbracket {\Sugar{\tttf]}}
+\unexpanded\def\module_syntax_Or {\Sugar{\mathematics{\vert}}}
+\unexpanded\def\module_syntax_Optional #1{\Sugar{\mathematics{[\hbox{#1}]}}}
+\unexpanded\def\module_syntax_Means {\Sugar{\mathematics{\rightarrow}}}
+\unexpanded\def\module_syntax_Tex #1{\Sugar{\type{#1}}}
+\unexpanded\def\module_syntax_Literal #1{\Sugar{\type{#1}}}
+\unexpanded\def\module_syntax_Syntax #1{\strut\kern-.25em{#1}\kern-.25em}
+\unexpanded\def\module_syntax_Next {\crlf\hbox to 2em{}\nobreak}
+\unexpanded\def\module_syntax_Whatever #1{\Sugar{\mathematics{(\hbox{#1})}}}
+\unexpanded\def\module_syntax_Quote #1{\Sugar{\quote{#1}}}
+\unexpanded\def\module_syntax_Or {\Sugar{\module_syntax_Indent{\mathematics{\vert}}}}
+\unexpanded\def\module_syntax_Means {\Sugar{\module_syntax_Indent{\mathematics{\rightarrow}}}}
+\unexpanded\def\module_syntax_FlaggedLiteral #1{\color[darkred]{\module_syntax_Literal{#1}}}
+\unexpanded\def\module_syntax_FlaggedSomething#1{\module_syntax_Something{\color[darkred]{#1}}}
+
+\unexpanded\def\StartSyntax
+ {\startlines
+ % formatters
+ \let\Indent \module_syntax_Indent
+ \let\Sugar \module_syntax_Sugar
+ \let\Something \module_syntax_Something
+ \let\Lbrace \module_syntax_Lbrace
+ \let\Rbrace \module_syntax_Rbrace
+ \let\Lparent \module_syntax_Lparent
+ \let\Rparent \module_syntax_Rparent
+ \let\Lbracket \module_syntax_Lbracket
+ \let\Rbracket \module_syntax_Rbracket
+ \let\Or \module_syntax_Or
+ \let\Optional \module_syntax_Optional
+ \let\Means \module_syntax_Means
+ \let\Tex \module_syntax_Tex
+ \let\Literal \module_syntax_Literal
+ \let\Syntax \module_syntax_Syntax
+ \let\Next \module_syntax_Next
+ \let\Whatever \module_syntax_Whatever
+ \let\Quote \module_syntax_Quote
+ \let\Or \module_syntax_Or
+ \let\Means \module_syntax_Means
+ \let\FlaggedLiteral \module_syntax_FlaggedLiteral
+ \let\FlaggedSomething\module_syntax_FlaggedSomething
+ % shortcuts
+ \let\FL \module_syntax_FlaggedLiteral
+ \let\FS \module_syntax_FlaggedSomething
+ \let\L \module_syntax_Literal
+ \let\S \module_syntax_Something
+ \let\M \module_syntax_Means
+ \let\O \module_syntax_Or
+ \let\Q \module_syntax_Quote
+ \let\LB \module_syntax_Lbrace
+ \let\RB \module_syntax_Rbrace
+ \let\LP \module_syntax_Lparent
+ \let\RP \module_syntax_Rparent
+ \let\LS \module_syntax_Lbracket
+ \let\RS \module_syntax_Rbracket
+ \let\{ \module_syntax_Lbrace
+ \let\} \module_syntax_Rbrace
+ \let\( \module_syntax_Lparent
+ \let\) \module_syntax_Rparent
+ \let\[ \module_syntax_Lbracket
+ \let\] \module_syntax_Rbracket
+ % precaution
+ \catcode`\#\othercatcode}
+
+\unexpanded\def\StopSyntax
+ {\stoplines}
+
+\unexpanded\def\SyntaxCommand#1%
+ {\csname module_syntax_#1\endcsname}
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/s-typesetting-kerning.mkiv b/tex/context/modules/mkiv/s-typesetting-kerning.mkiv
new file mode 100644
index 000000000..48d81ce36
--- /dev/null
+++ b/tex/context/modules/mkiv/s-typesetting-kerning.mkiv
@@ -0,0 +1,209 @@
+%D \module
+%D [ file=s-typesetting-kerning,
+%D version=2014.12.14,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Show Character Kerning,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\unprotect
+
+\definecharacterkerning
+ [typesetting-kerning-demo]
+ [factor=.5]
+
+\startbuffer[showcharacterkerning:boxes]
+ \starttextrule{boxes}
+ \showfontkerns
+ \dontcomplain
+ \startlines
+ test \hbox{!} test
+ test\hbox{!} test
+ test \hbox{!}test
+ test:$x$ test
+ \setcharacterkerning[typesetting-kerning-demo]
+ test \hbox{!} test
+ test\hbox{!} test
+ test \hbox{!}test
+ test:$x$ test
+ \stoplines
+ \stoptextrule
+\stopbuffer
+
+\startbuffer[showcharacterkerning:ligatures]
+ \starttextrule{ligatures}
+ \dontcomplain
+ \startlines
+ effe flink effectief efficient fietsen
+ \blank
+ \setcharacterkerning[typesetting-kerning-demo]
+ effe flink effectief efficient fietsen
+ \blank \hsize\zeropoint
+ effe
+ flink
+ effectief
+ efficient
+ fietsen
+ \stoplines
+ \stoptextrule
+\stopbuffer
+
+\startbuffer[showcharacterkerning:discretionaries]
+ \starttextrule{discretionary}
+ \dontcomplain
+ \startlines
+ \hbox{\samplediscretionary}
+ \hbox{xxx\samplediscretionary}
+ \hbox{\samplediscretionary xxx}
+ \hbox{xxx\samplediscretionary xxx}
+ \blank
+ \setcharacterkerning[typesetting-kerning-demo]
+ \hbox{\samplediscretionary}
+ \hbox{xxx\samplediscretionary}
+ \hbox{\samplediscretionary xxx}
+ \hbox{xxx\samplediscretionary xxx}
+ \blank \hsize\zeropoint
+ \samplediscretionary
+ xxx\samplediscretionary
+ \samplediscretionary xxx
+ xxx\samplediscretionary xxx
+ \stoplines
+ \stoptextrule
+\stopbuffer
+
+\startbuffer[showcharacterkerning:explicits]
+ \starttextrule{explicits}
+ \exhyphenchar \hyphenasciicode
+ \preexhyphenchar \lessthanasciicode
+ \postexhyphenchar\morethanasciicode
+ \def\TestDisc
+ {\discretionary
+ {\kern\emwidth<}%
+ {>\kern\emwidth}%
+ {\kern\emwidth=\kern\emwidth}%
+ }
+ \dontcomplain
+ \startlines
+ \hbox{super-charged}
+ \hbox{super\-charged}
+ \hbox{super\TestDisc charged}
+ \hbox{super\discretionary{[}{]}{[]}charged}
+ \blank
+ \setcharacterkerning[typesetting-kerning-demo]
+ \hbox{super-charged}
+ \hbox{super\-charged}
+ \hbox{super\TestDisc charged}
+ \hbox{super\discretionary{[}{]}{[]}charged}
+ \blank \hsize\zeropoint
+ super-charged
+ super\-charged
+ super\TestDisc charged
+ super\discretionary{[}{]}{[]}charged
+ \stoplines
+ \stoptextrule
+\stopbuffer
+
+\starttexdefinition unexpanded showcharacterkerning
+ \getbuffer[showcharacterkerning:boxes]
+ \getbuffer[showcharacterkerning:ligatures]
+ \getbuffer[showcharacterkerning:discretionaries]
+ \getbuffer[showcharacterkerning:explicits]
+\stoptexdefinition
+
+
+\starttexdefinition showcharacterkerningstepscompared #1
+ \definecharacterkerning[crap][factor=\KerningStepFactor]%
+ \setbox0=\ruledhbox{\color[color-1]{#1}\hss}
+ \setbox2=\ruledhbox{\setcharacterkerning[crap]\color[color-2]{#1}}
+ \setbox4=\ruledhbox{\setcharacterkerning[crap]\showfontkerns\showglyphs#1}
+ \xdef\KerningStepPercentage{\ctxlua{context("\letterpercent 0.2f",(1-\number\wd0/\number\wd2)*100)}}
+ \scratchwidth\wd0
+ \vtop\bgroup
+ \hbox{\box0\hskip-\scratchwidth\box2}
+ \par
+ \box4
+ \egroup
+\stoptexdefinition
+
+\starttexdefinition showcharacterkerningsteps [#1]
+
+ \start
+
+ \getdummyparameters
+ [\s!font=Regular,
+ \c!sample={Wat een bende, rommelen met het font design!},
+ \c!text={rommelen},
+ \c!first=00,
+ \c!last=95,
+ \c!step=05,
+ \c!option=, % \v!page
+ #1]
+
+ \doif{\dummyparameter\c!option}\v!page {
+ \startTEXpage[\c!offset=1ex]
+ }
+
+ \definecolor[color-1][r=1,t=.5,a=1]
+ \definecolor[color-2][b=1,t=.5,a=1]
+
+ \definedfont[\dummyparameter\s!font*default sa 1]
+
+ \doif {\dummyparameter\c!option}\v!page {
+ \begingroup
+ \tttf \dummyparameter\s!font\space @ default
+ \endgroup
+ \blank
+ }
+
+ \starttabulate[|cT|l|cT|l|cT|]
+
+ \NC \tt\bf factor \NC \tt\bf sample \NC \tt\bf \letterpercent \NC \tt\bf text \NC \tt\bf \letterpercent \NC \NR \HL
+
+ \dostepwiserecurse {\dummyparameter\c!first} {\dummyparameter\c!last} {\dummyparameter\c!step} {
+ \NC
+ \xdef\KerningStepFactor{\ctxlua{context("\letterpercent 0.3f",####1/1000)}}
+ \KerningStepFactor
+ \NC
+ \showcharacterkerningstepscompared{\dummyparameter\c!sample}
+ \NC
+ \KerningStepPercentage
+ \NC
+ \showcharacterkerningstepscompared{\dummyparameter\c!text}
+ \NC
+ \KerningStepPercentage
+ \NC \NR
+ }
+
+ \stoptabulate
+
+ \doif{\dummyparameter\c!option}\v!page {
+ \stopTEXpage
+ }
+
+ \stop
+
+\stoptexdefinition
+
+\protect
+
+\continueifinputfile{s-typesetting-kerning.mkiv}
+
+\starttext
+
+ % \showcharacterkerning
+
+ \showcharacterkerningsteps[font=file:FuturaStd-Book.otf,option=page]
+ \showcharacterkerningsteps[font=file:FuturaStd-Medium.otf,option=page]
+ \showcharacterkerningsteps[font=file:FuturaStd-Bold.otf,option=page]
+ \showcharacterkerningsteps[font=file:FuturaStd-heavy.otf,option=page]
+
+\stoptext
+
+% {\hsize1mm efficient\discretionary{\kern1pt!\kern1pt}{\kern1pt!\kern1pt}{\kern1pt!\kern1pt}efficient\par}
+% {\hsize1mm\definedfont[Regular]\setcharacterkerning[typesetting-kerning-demo]efficient\-efficient\par}
+
diff --git a/tex/context/modules/mkiv/s-youless.mkiv b/tex/context/modules/mkiv/s-youless.mkiv
new file mode 100644
index 000000000..e15973b9c
--- /dev/null
+++ b/tex/context/modules/mkiv/s-youless.mkiv
@@ -0,0 +1,171 @@
+%D \module
+%D [ file=s-youless,
+%D version=2013.11.12,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Youless Graphics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is experimental code. When I have collected enough data I will make the
+%D graphics nicer and provide some more.
+%D
+%D The Jouless can serve web pages but there is not much detail in them. They also are
+%D somewhat bad \HTML, like unquoted attributes and so. We don't need this anyway as we
+%D can also fetch data directly. The data is collected using a dedicated helper script
+%D (of course we could just call it as module too). The data is fetched from the Jouless
+%D device using queries (currently we use json, but a more direct parsing of data might
+%D be more efficient). The data is converted into a proper \LUA\ table and saved (merged).
+
+% in cronjob on one of the servers:
+%
+% mtxrun --script youless --collect --host=192.168.2.50 --watt youless-watt.lua
+% mtxrun --script youless --collect --host=192.168.2.50 --kwk youless-kwh.lua
+
+\startluacode
+
+ require("util-you")
+
+ moduledata.youless = { }
+
+ function moduledata.youless.kwh(specification)
+ -- todo
+ end
+
+ function moduledata.youless.watt(specification)
+
+ local year = tonumber(specification.year) or os.today().year
+ local data = table.load(specification.filename or "youless-watt.lua")
+
+ if not data or data.variant ~= "watt" then
+ context("invalid variant")
+ return
+ end
+
+ utilities.youless.analyze(data)
+
+ -- for the moment no specific font scaling
+
+ local years = data.years
+
+ if not years then
+ context("no years")
+ return
+ end
+
+ for y=year,year do
+
+ local year = years[y]
+ local scale = 20
+ local mark = 3
+ local maxwatt = specification.maxwatt or year.maxwatt
+
+ for m=1,12 do
+ local month = year.months[m]
+ if month then
+ context.startMPpage { offset = "10pt" }
+ context("linecap := butt; pickup pencircle scaled .5")
+
+ for i=0,(math.div(maxwatt,1000)+1)*1000,100 do
+ context("draw (%s,%s) -- (%s,%s) withcolor .6white ;",0,i/scale,31 * 24,i/scale)
+ end
+
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(on 6 off 6) withcolor darkgreen withpen pencircle scaled 1 ;",year.watt /scale,year.watt /scale)
+ context("draw (0,%s) -- (31 * 24,%s) dashed dashpattern(off 6 on 6) withcolor darkred withpen pencircle scaled 1 ;",month.watt/scale,month.watt/scale)
+
+ local days = month.days
+ if days then
+ local nd = os.nofdays(y,m)
+ for d=1,nd do
+ local day = days[d]
+ local xoffset = (d-1) * 24
+ local wd = os.weekday(d,m,y)
+ local weekend = wd == 1 or wd == 7
+ if not weekend then
+ -- okay
+ elseif mark == 1 then
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset, -32.5)
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset+24,-17.5,xoffset+24,-32.5)
+ elseif mark == 2 then
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -17.5,xoffset+24,-17.5)
+ context("draw (%s,%s) -- (%s,%s) ; ",xoffset, -32.5,xoffset+24,-32.5)
+ elseif mark == 3 then
+ context("draw unitsquare xysized (%s,%s) shifted (%s,%s) ; ",24,15,xoffset,-32.5)
+ end
+ context([[draw textext("%s") shifted (%s,%s) ; ]],d,xoffset + 12,-25)
+ if day then
+ for h=0,23 do
+ local hours = day.hours
+ if hours then
+ local hour = hours[h]
+ if hour then
+ local dx = xoffset + h
+ local dy = hour.watt/scale
+ local dm = hour.maxwatt/scale
+ context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx, 0,dx,dy,weekend and "darkmagenta" or "darkblue")
+ context("draw (%s,%s) -- (%s,%s) withcolor %s ; ",dx,dy,dx,dm,"darkgray")
+ end
+ end
+ end
+ end
+ end
+ for d=0,30 do
+ local xoffset = d * 24
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 0,0,xoffset+ 0,-10)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+ 6,0,xoffset+ 6,-2.5)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+12,0,xoffset+12,-5)
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset+18,0,xoffset+18,-2.5)
+ end
+ local xoffset = 31 * 24
+ context("draw (%s,%s) -- (%s,%s) withcolor darkgray ; ",xoffset,0,xoffset,-10)
+ end
+
+ local max = (math.div(maxwatt,1000)+1)
+
+ for i=0,max*1000,1000 do
+ context([[draw textext.lft("%s") shifted (%s,%s) ; ]],i,-10,i/scale)
+ context("draw (%s,%s) -- (%s,%s) withcolor .2white ;",0,i/scale,31 * 24,i/scale)
+ end
+
+ context([[draw textext("\strut\month{%s}\enspace%s") shifted (%s,%s) ; ]],m, y, 31 * 24 / 2, -50)
+ context([[draw textext.lft("watt") shifted (%s,%s) ; ]],-10,-25)
+
+ context.stopMPpage()
+ else
+ -- maybe placeholder
+ end
+ end
+
+ end
+
+ end
+
+\stopluacode
+
+\continueifinputfile{s-youless.mkiv}
+
+\setupbodyfont[dejavu] % smaller sizes also look ok
+
+% printer (oce) : > 3000 W startup (900 W idle, 2000 W printing)
+% coffeemaker : 1500 W when heating
+
+% baseline day : 2250 W (servers, airco, workstations, routers, switches, heating, etc)
+% baseline night : 1750 W
+
+\starttext
+
+ \startluacode
+
+ -- os.execute([[mtxrun --script youless --collect --watt "c:/data/system/youless/data/youless-watt.lua"]])
+ -- os.execute([[mtxrun --script youless --collect --watt --nobackup "c:/data/system/youless/data/youless-watt.lua"]])
+ -- moduledata.youless.watt { year = 2013, filename = "c:/data/system/youless/data/youless-watt.lua" }
+
+ moduledata.youless.watt { year = 2013, filename = "youless-watt.lua" }
+
+ \stopluacode
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-asciimath.lua b/tex/context/modules/mkiv/x-asciimath.lua
new file mode 100644
index 000000000..e0a4a714b
--- /dev/null
+++ b/tex/context/modules/mkiv/x-asciimath.lua
@@ -0,0 +1,2209 @@
+if not modules then modules = { } end modules ['x-asciimath'] = {
+ version = 1.001,
+ comment = "companion to x-asciimath.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[ldx--
+<p>Some backgrounds are discussed in <t>x-asciimath.mkiv</t>. This is a third version. I first
+tried a to make a proper expression parser but it's not that easy. First we have to avoid left
+recursion, which is not that trivial (maybe a future version of lpeg will provide that), and
+second there is not really a syntax but a mix of expressions and sequences with some fuzzy logic
+applied. Most problematic are fractions and we also need to handle incomplete expressions. So,
+instead we (sort of) tokenize the string and then do some passes over the result. Yes, it's real
+ugly and unsatisfying code mess down here. Don't take this as an example.</p>
+--ldx]]--
+
+-- todo: spaces around all elements in cleanup?
+-- todo: filter from files listed in tuc file
+
+local trace_mapping = false if trackers then trackers.register("modules.asciimath.mapping", function(v) trace_mapping = v end) end
+local trace_detail = false if trackers then trackers.register("modules.asciimath.detail", function(v) trace_detail = v end) end
+local trace_digits = false if trackers then trackers.register("modules.asciimath.digits", function(v) trace_digits = v end) end
+
+local report_asciimath = logs.reporter("mathematics","asciimath")
+
+local asciimath = { }
+local moduledata = moduledata or { }
+moduledata.asciimath = asciimath
+
+if not characters then
+ require("char-def")
+ require("char-ini")
+ require("char-ent")
+end
+
+local type, rawget = type, rawget
+local concat, insert, remove = table.concat, table.insert, table.remove
+local rep, gmatch, gsub, find = string.rep, string.gmatch, string.gsub, string.find
+local utfchar, utfbyte = utf.char, utf.byte
+
+local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local S, P, R, C, V, Cc, Ct, Cs, Carg = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct, lpeg.Cs, lpeg.Carg
+
+local sortedhash = table.sortedhash
+local sortedkeys = table.sortedkeys
+local formatters = string.formatters
+
+local entities = characters.entities or { }
+
+local xmltext = xml.text
+local xmlinclusion = xml.inclusion
+local xmlcollected = xml.collected
+
+-- todo: use private unicodes as temporary slots ... easier to compare
+
+local s_lparent = "\\left\\lparent"
+local s_lbrace = "\\left\\lbrace"
+local s_lbracket = "\\left\\lbracket"
+local s_langle = "\\left\\langle"
+local s_lfloor = "\\left\\lfloor"
+local s_lceil = "\\left\\lceil"
+local s_left = "\\left."
+
+local s_rparent = "\\right\\rparent"
+local s_rbrace = "\\right\\rbrace"
+local s_rbracket = "\\right\\rbracket"
+local s_rangle = "\\right\\rangle"
+local s_rfloor = "\\right\\rfloor"
+local s_rceil = "\\right\\rceil"
+local s_right = "\\right."
+
+local s_mslash = "\\middle/"
+
+local s_lbar = "\\left\\|"
+local s_mbar = "\\middle\\|"
+local s_rbar = "\\right\\|"
+
+local s_lnothing = "\\left ." -- space fools checker
+local s_rnothing = "\\right ." -- space fools checker
+
+local reserved = {
+
+ ["prod"] = { false, "\\prod" },
+ ["sinh"] = { false, "\\sinh" },
+ ["cosh"] = { false, "\\cosh" },
+ ["tanh"] = { false, "\\tanh" },
+ ["sum"] = { false, "\\sum" },
+ ["int"] = { false, "\\int" },
+ ["sin"] = { false, "\\sin" },
+ ["cos"] = { false, "\\cos" },
+ ["tan"] = { false, "\\tan" },
+ ["csc"] = { false, "\\csc" },
+ ["sec"] = { false, "\\sec" },
+ ["cot"] = { false, "\\cot" },
+ ["log"] = { false, "\\log" },
+ ["det"] = { false, "\\det" },
+ ["lim"] = { false, "\\lim" },
+ ["mod"] = { false, "\\mod" },
+ ["gcd"] = { false, "\\gcd" },
+ ["min"] = { false, "\\min" },
+ ["max"] = { false, "\\max" },
+ ["ln"] = { false, "\\ln" },
+
+ ["atan"] = { false, "\\atan" }, -- extra
+ ["acos"] = { false, "\\acos" }, -- extra
+ ["asin"] = { false, "\\asin" }, -- extra
+
+ ["arctan"] = { false, "\\arctan" }, -- extra
+ ["arccos"] = { false, "\\arccos" }, -- extra
+ ["arcsin"] = { false, "\\arcsin" }, -- extra
+
+ ["and"] = { false, "\\text{and}" },
+ ["or"] = { false, "\\text{or}" },
+ ["if"] = { false, "\\text{if}" },
+
+ ["sqrt"] = { false, "\\asciimathsqrt", "unary" },
+ ["root"] = { false, "\\asciimathroot", "binary" },
+ -- ["\\frac"] = { false, "\\frac", "binary" },
+ ["frac"] = { false, "\\frac", "binary" },
+ ["stackrel"] = { false, "\\asciimathstackrel", "binary" },
+ ["hat"] = { false, "\\widehat", "unary" },
+ ["bar"] = { false, "\\overbar", "unary" },
+ ["overbar"] = { false, "\\overbar", "unary" },
+ ["underline"] = { false, "\\underline", "unary" },
+ ["ul"] = { false, "\\underline", "unary" },
+ ["vec"] = { false, "\\overrightarrow", "unary" },
+ ["dot"] = { false, "\\dot", "unary" }, -- 0x2D9
+ ["ddot"] = { false, "\\ddot", "unary" }, -- 0xA8
+
+ -- binary operators
+
+ ["+"] = { true, "+" },
+ ["-"] = { true, "-" },
+ ["*"] = { true, "⋅" },
+ ["**"] = { true, "⋆" },
+ ["//"] = { true, "⁄" }, -- \slash
+ ["\\"] = { true, "\\" },
+ ["xx"] = { true, "×" },
+ ["times"] = { true, "×" },
+ ["-:"] = { true, "÷" },
+ ["@"] = { true, "∘" },
+ ["circ"] = { true, "∘" },
+ ["o+"] = { true, "⊕" },
+ ["ox"] = { true, "⊗" },
+ ["o."] = { true, "⊙" },
+ ["^^"] = { true, "∧" },
+ ["vv"] = { true, "∨" },
+ ["nn"] = { true, "∩" },
+ ["uu"] = { true, "∪" },
+
+ -- big operators
+
+ ["^^^"] = { true, "⋀" },
+ ["vvv"] = { true, "⋁" },
+ ["nnn"] = { true, "⋂" },
+ ["uuu"] = { true, "⋃" },
+ ["int"] = { true, "∫" },
+ ["oint"] = { true, "∮" },
+
+ -- brackets
+
+ ["("] = { true, "(" },
+ [")"] = { true, ")" },
+ ["["] = { true, "[" },
+ ["]"] = { true, "]" },
+ ["{"] = { true, "{" },
+ ["}"] = { true, "}" },
+
+ -- binary relations
+
+ ["="] = { true, "=" },
+ ["eq"] = { true, "=" },
+ ["!="] = { true, "≠" },
+ ["ne"] = { true, "≠" },
+ ["neq"] = { true, "≠" },
+ ["<"] = { true, "<" },
+ ["lt"] = { true, "<" },
+ [">"] = { true, ">" },
+ ["gt"] = { true, ">" },
+ ["<="] = { true, "≤" },
+ ["le"] = { true, "≤" },
+ ["leq"] = { true, "≤" },
+ [">="] = { true, "≥" },
+ ["ge"] = { true, "≥" },
+ ["geq"] = { true, "≥" },
+ ["-<"] = { true, "≺" },
+ [">-"] = { true, "≻" },
+ ["in"] = { true, "∈" },
+ ["!in"] = { true, "∉" },
+ ["sub"] = { true, "⊂" },
+ ["sup"] = { true, "⊃" },
+ ["sube"] = { true, "⊆" },
+ ["supe"] = { true, "⊇" },
+ ["-="] = { true, "≡" },
+ ["~="] = { true, "≅" },
+ ["~~"] = { true, "≈" },
+ ["prop"] = { true, "∝" },
+
+ -- arrows
+
+ ["rarr"] = { true, "→" },
+ ["->"] = { true, "→" },
+ ["larr"] = { true, "←" },
+ ["harr"] = { true, "↔" },
+ ["uarr"] = { true, "↑" },
+ ["darr"] = { true, "↓" },
+ ["rArr"] = { true, "⇒" },
+ ["lArr"] = { true, "⇐" },
+ ["hArr"] = { true, "⇔" },
+ ["|->"] = { true, "↦" },
+
+ -- logical
+
+ ["not"] = { true, "¬" },
+ ["=>"] = { true, "⇒" },
+ ["iff"] = { true, "⇔" },
+ ["AA"] = { true, "∀" },
+ ["EE"] = { true, "∃" },
+ ["_|_"] = { true, "⊥" },
+ ["TT"] = { true, "⊤" },
+ ["|--"] = { true, "⊢" },
+ ["|=="] = { true, "⊨" },
+
+ -- miscellaneous
+
+ ["del"] = { true, "∂" },
+ ["grad"] = { true, "∇" },
+ ["+-"] = { true, "±" },
+ ["O/"] = { true, "∅" },
+ ["oo"] = { true, "∞" },
+ ["aleph"] = { true, "ℵ" },
+ ["angle"] = { true, "∠" },
+ ["/_"] = { true, "∠" },
+ [":."] = { true, "∴" },
+ ["..."] = { true, "..." }, -- ldots
+ ["ldots"] = { true, "..." }, -- ldots
+ ["cdots"] = { true, "⋯" },
+ ["vdots"] = { true, "⋮" },
+ ["ddots"] = { true, "⋱" },
+ ["diamond"] = { true, "⋄" },
+ ["square"] = { true, "□" },
+ ["|__"] = { true, "⌊" },
+ ["__|"] = { true, "⌋" },
+ ["|~"] = { true, "⌈" },
+ ["~|"] = { true, "⌉" },
+
+ -- more
+
+ ["_="] = { true, "≡" },
+
+ -- bonus
+
+ ["prime"] = { true, "′" }, -- bonus
+ ["'"] = { true, "′" }, -- bonus
+ ["''"] = { true, "″" }, -- bonus
+ ["'''"] = { true, "‴" }, -- bonus
+
+ -- special
+
+ ["%"] = { false, "\\mathpercent" },
+ ["&"] = { false, "\\mathampersand" },
+ ["#"] = { false, "\\mathhash" },
+ ["$"] = { false, "\\mathdollar" },
+
+ -- blackboard
+
+ ["CC"] = { true, "ℂ" },
+ ["NN"] = { true, "ℕ" },
+ ["QQ"] = { true, "ℚ" },
+ ["RR"] = { true, "ℝ" },
+ ["ZZ"] = { true, "ℤ" },
+
+ -- greek lowercase
+
+ ["alpha"] = { true, "α" },
+ ["beta"] = { true, "β" },
+ ["gamma"] = { true, "γ" },
+ ["delta"] = { true, "δ" },
+ ["epsilon"] = { true, "ε" },
+ ["varepsilon"] = { true, "ɛ" },
+ ["zeta"] = { true, "ζ" },
+ ["eta"] = { true, "η" },
+ ["theta"] = { true, "θ" },
+ ["vartheta"] = { true, "ϑ" },
+ ["iota"] = { true, "ι" },
+ ["kappa"] = { true, "κ" },
+ ["lambda"] = { true, "λ" },
+ ["mu"] = { true, "μ" },
+ ["nu"] = { true, "ν" },
+ ["xi"] = { true, "ξ" },
+ ["pi"] = { true, "π" },
+ ["rho"] = { true, "ρ" },
+ ["sigma"] = { true, "σ" },
+ ["tau"] = { true, "τ" },
+ ["upsilon"] = { true, "υ" },
+ ["phi"] = { true, "φ" },
+ ["varphi"] = { true, "ϕ" },
+ ["chi"] = { true, "χ" },
+ ["psi"] = { true, "ψ" },
+ ["omega"] = { true, "ω" },
+
+ -- greek uppercase
+
+ ["Gamma"] = { true, "Γ" },
+ ["Delta"] = { true, "Δ" },
+ ["Theta"] = { true, "Θ" },
+ ["Lambda"] = { true, "Λ" },
+ ["Xi"] = { true, "Ξ" },
+ ["Pi"] = { true, "Π" },
+ ["Sigma"] = { true, "Σ" },
+ ["Phi"] = { true, "Φ" },
+ ["Psi"] = { true, "Ψ" },
+ ["Omega"] = { true, "Ω" },
+
+ -- blackboard
+
+ ["bbb a"] = { true, "𝕒" },
+ ["bbb b"] = { true, "𝕓" },
+ ["bbb c"] = { true, "𝕔" },
+ ["bbb d"] = { true, "𝕕" },
+ ["bbb e"] = { true, "𝕖" },
+ ["bbb f"] = { true, "𝕗" },
+ ["bbb g"] = { true, "𝕘" },
+ ["bbb h"] = { true, "𝕙" },
+ ["bbb i"] = { true, "𝕚" },
+ ["bbb j"] = { true, "𝕛" },
+ ["bbb k"] = { true, "𝕜" },
+ ["bbb l"] = { true, "𝕝" },
+ ["bbb m"] = { true, "𝕞" },
+ ["bbb n"] = { true, "𝕟" },
+ ["bbb o"] = { true, "𝕠" },
+ ["bbb p"] = { true, "𝕡" },
+ ["bbb q"] = { true, "𝕢" },
+ ["bbb r"] = { true, "𝕣" },
+ ["bbb s"] = { true, "𝕤" },
+ ["bbb t"] = { true, "𝕥" },
+ ["bbb u"] = { true, "𝕦" },
+ ["bbb v"] = { true, "𝕧" },
+ ["bbb w"] = { true, "𝕨" },
+ ["bbb x"] = { true, "𝕩" },
+ ["bbb y"] = { true, "𝕪" },
+ ["bbb z"] = { true, "𝕫" },
+
+ ["bbb A"] = { true, "𝔸" },
+ ["bbb B"] = { true, "𝔹" },
+ ["bbb C"] = { true, "ℂ" },
+ ["bbb D"] = { true, "𝔻" },
+ ["bbb E"] = { true, "𝔼" },
+ ["bbb F"] = { true, "𝔽" },
+ ["bbb G"] = { true, "𝔾" },
+ ["bbb H"] = { true, "ℍ" },
+ ["bbb I"] = { true, "𝕀" },
+ ["bbb J"] = { true, "𝕁" },
+ ["bbb K"] = { true, "𝕂" },
+ ["bbb L"] = { true, "𝕃" },
+ ["bbb M"] = { true, "𝕄" },
+ ["bbb N"] = { true, "ℕ" },
+ ["bbb O"] = { true, "𝕆" },
+ ["bbb P"] = { true, "ℙ" },
+ ["bbb Q"] = { true, "ℚ" },
+ ["bbb R"] = { true, "ℝ" },
+ ["bbb S"] = { true, "𝕊" },
+ ["bbb T"] = { true, "𝕋" },
+ ["bbb U"] = { true, "𝕌" },
+ ["bbb V"] = { true, "𝕍" },
+ ["bbb W"] = { true, "𝕎" },
+ ["bbb X"] = { true, "𝕏" },
+ ["bbb Y"] = { true, "𝕐" },
+ ["bbb Z"] = { true, "ℤ" },
+
+ -- fraktur
+
+ ["fr a"] = { true, "𝔞" },
+ ["fr b"] = { true, "𝔟" },
+ ["fr c"] = { true, "𝔠" },
+ ["fr d"] = { true, "𝔡" },
+ ["fr e"] = { true, "𝔢" },
+ ["fr f"] = { true, "𝔣" },
+ ["fr g"] = { true, "𝔤" },
+ ["fr h"] = { true, "𝔥" },
+ ["fr i"] = { true, "𝔦" },
+ ["fr j"] = { true, "𝔧" },
+ ["fr k"] = { true, "𝔨" },
+ ["fr l"] = { true, "𝔩" },
+ ["fr m"] = { true, "𝔪" },
+ ["fr n"] = { true, "𝔫" },
+ ["fr o"] = { true, "𝔬" },
+ ["fr p"] = { true, "𝔭" },
+ ["fr q"] = { true, "𝔮" },
+ ["fr r"] = { true, "𝔯" },
+ ["fr s"] = { true, "𝔰" },
+ ["fr t"] = { true, "𝔱" },
+ ["fr u"] = { true, "𝔲" },
+ ["fr v"] = { true, "𝔳" },
+ ["fr w"] = { true, "𝔴" },
+ ["fr x"] = { true, "𝔵" },
+ ["fr y"] = { true, "𝔶" },
+ ["fr z"] = { true, "𝔷" },
+
+ ["fr A"] = { true, "𝔄" },
+ ["fr B"] = { true, "𝔅" },
+ ["fr C"] = { true, "ℭ" },
+ ["fr D"] = { true, "𝔇" },
+ ["fr E"] = { true, "𝔈" },
+ ["fr F"] = { true, "𝔉" },
+ ["fr G"] = { true, "𝔊" },
+ ["fr H"] = { true, "ℌ" },
+ ["fr I"] = { true, "ℑ" },
+ ["fr J"] = { true, "𝔍" },
+ ["fr K"] = { true, "𝔎" },
+ ["fr L"] = { true, "𝔏" },
+ ["fr M"] = { true, "𝔐" },
+ ["fr N"] = { true, "𝔑" },
+ ["fr O"] = { true, "𝔒" },
+ ["fr P"] = { true, "𝔓" },
+ ["fr Q"] = { true, "𝔔" },
+ ["fr R"] = { true, "ℜ" },
+ ["fr S"] = { true, "𝔖" },
+ ["fr T"] = { true, "𝔗" },
+ ["fr U"] = { true, "𝔘" },
+ ["fr V"] = { true, "𝔙" },
+ ["fr W"] = { true, "𝔚" },
+ ["fr X"] = { true, "𝔛" },
+ ["fr Y"] = { true, "𝔜" },
+ ["fr Z"] = { true, "ℨ" },
+
+ -- script
+
+ ["cc a"] = { true, "𝒶" },
+ ["cc b"] = { true, "𝒷" },
+ ["cc c"] = { true, "𝒸" },
+ ["cc d"] = { true, "𝒹" },
+ ["cc e"] = { true, "ℯ" },
+ ["cc f"] = { true, "𝒻" },
+ ["cc g"] = { true, "ℊ" },
+ ["cc h"] = { true, "𝒽" },
+ ["cc i"] = { true, "𝒾" },
+ ["cc j"] = { true, "𝒿" },
+ ["cc k"] = { true, "𝓀" },
+ ["cc l"] = { true, "𝓁" },
+ ["cc m"] = { true, "𝓂" },
+ ["cc n"] = { true, "𝓃" },
+ ["cc o"] = { true, "ℴ" },
+ ["cc p"] = { true, "𝓅" },
+ ["cc q"] = { true, "𝓆" },
+ ["cc r"] = { true, "𝓇" },
+ ["cc s"] = { true, "𝓈" },
+ ["cc t"] = { true, "𝓉" },
+ ["cc u"] = { true, "𝓊" },
+ ["cc v"] = { true, "𝓋" },
+ ["cc w"] = { true, "𝓌" },
+ ["cc x"] = { true, "𝓍" },
+ ["cc y"] = { true, "𝓎" },
+ ["cc z"] = { true, "𝓏" },
+
+ ["cc A"] = { true, "𝒜" },
+ ["cc B"] = { true, "ℬ" },
+ ["cc C"] = { true, "𝒞" },
+ ["cc D"] = { true, "𝒟" },
+ ["cc E"] = { true, "ℰ" },
+ ["cc F"] = { true, "ℱ" },
+ ["cc G"] = { true, "𝒢" },
+ ["cc H"] = { true, "ℋ" },
+ ["cc I"] = { true, "ℐ" },
+ ["cc J"] = { true, "𝒥" },
+ ["cc K"] = { true, "𝒦" },
+ ["cc L"] = { true, "ℒ" },
+ ["cc M"] = { true, "ℳ" },
+ ["cc N"] = { true, "𝒩" },
+ ["cc O"] = { true, "𝒪" },
+ ["cc P"] = { true, "𝒫" },
+ ["cc Q"] = { true, "𝒬" },
+ ["cc R"] = { true, "ℛ" },
+ ["cc S"] = { true, "𝒮" },
+ ["cc T"] = { true, "𝒯" },
+ ["cc U"] = { true, "𝒰" },
+ ["cc V"] = { true, "𝒱" },
+ ["cc W"] = { true, "𝒲" },
+ ["cc X"] = { true, "𝒳" },
+ ["cc Y"] = { true, "𝒴" },
+ ["cc Z"] = { true, "𝒵" },
+
+ -- bold
+
+ ["bb a"] = { true, "𝒂" },
+ ["bb b"] = { true, "𝒃" },
+ ["bb c"] = { true, "𝒄" },
+ ["bb d"] = { true, "𝒅" },
+ ["bb e"] = { true, "𝒆" },
+ ["bb f"] = { true, "𝒇" },
+ ["bb g"] = { true, "𝒈" },
+ ["bb h"] = { true, "𝒉" },
+ ["bb i"] = { true, "𝒊" },
+ ["bb j"] = { true, "𝒋" },
+ ["bb k"] = { true, "𝒌" },
+ ["bb l"] = { true, "𝒍" },
+ ["bb m"] = { true, "𝒎" },
+ ["bb n"] = { true, "𝒏" },
+ ["bb o"] = { true, "𝒐" },
+ ["bb p"] = { true, "𝒑" },
+ ["bb q"] = { true, "𝒒" },
+ ["bb r"] = { true, "𝒓" },
+ ["bb s"] = { true, "𝒔" },
+ ["bb t"] = { true, "𝒕" },
+ ["bb u"] = { true, "𝒖" },
+ ["bb v"] = { true, "𝒗" },
+ ["bb w"] = { true, "𝒘" },
+ ["bb x"] = { true, "𝒙" },
+ ["bb y"] = { true, "𝒚" },
+ ["bb z"] = { true, "𝒛" },
+
+ ["bb A"] = { true, "𝑨" },
+ ["bb B"] = { true, "𝑩" },
+ ["bb C"] = { true, "𝑪" },
+ ["bb D"] = { true, "𝑫" },
+ ["bb E"] = { true, "𝑬" },
+ ["bb F"] = { true, "𝑭" },
+ ["bb G"] = { true, "𝑮" },
+ ["bb H"] = { true, "𝑯" },
+ ["bb I"] = { true, "𝑰" },
+ ["bb J"] = { true, "𝑱" },
+ ["bb K"] = { true, "𝑲" },
+ ["bb L"] = { true, "𝑳" },
+ ["bb M"] = { true, "𝑴" },
+ ["bb N"] = { true, "𝑵" },
+ ["bb O"] = { true, "𝑶" },
+ ["bb P"] = { true, "𝑷" },
+ ["bb Q"] = { true, "𝑸" },
+ ["bb R"] = { true, "𝑹" },
+ ["bb S"] = { true, "𝑺" },
+ ["bb T"] = { true, "𝑻" },
+ ["bb U"] = { true, "𝑼" },
+ ["bb V"] = { true, "𝑽" },
+ ["bb W"] = { true, "𝑾" },
+ ["bb X"] = { true, "𝑿" },
+ ["bb Y"] = { true, "𝒀" },
+ ["bb Z"] = { true, "𝒁" },
+
+ -- sans
+
+ ["sf a"] = { true, "𝖺" },
+ ["sf b"] = { true, "𝖻" },
+ ["sf c"] = { true, "𝖼" },
+ ["sf d"] = { true, "𝖽" },
+ ["sf e"] = { true, "𝖾" },
+ ["sf f"] = { true, "𝖿" },
+ ["sf g"] = { true, "𝗀" },
+ ["sf h"] = { true, "𝗁" },
+ ["sf i"] = { true, "𝗂" },
+ ["sf j"] = { true, "𝗃" },
+ ["sf k"] = { true, "𝗄" },
+ ["sf l"] = { true, "𝗅" },
+ ["sf m"] = { true, "𝗆" },
+ ["sf n"] = { true, "𝗇" },
+ ["sf o"] = { true, "𝗈" },
+ ["sf p"] = { true, "𝗉" },
+ ["sf q"] = { true, "𝗊" },
+ ["sf r"] = { true, "𝗋" },
+ ["sf s"] = { true, "𝗌" },
+ ["sf t"] = { true, "𝗍" },
+ ["sf u"] = { true, "𝗎" },
+ ["sf v"] = { true, "𝗏" },
+ ["sf w"] = { true, "𝗐" },
+ ["sf x"] = { true, "𝗑" },
+ ["sf y"] = { true, "𝗒" },
+ ["sf z"] = { true, "𝗓" },
+
+ ["sf A"] = { true, "𝖠" },
+ ["sf B"] = { true, "𝖡" },
+ ["sf C"] = { true, "𝖢" },
+ ["sf D"] = { true, "𝖣" },
+ ["sf E"] = { true, "𝖤" },
+ ["sf F"] = { true, "𝖥" },
+ ["sf G"] = { true, "𝖦" },
+ ["sf H"] = { true, "𝖧" },
+ ["sf I"] = { true, "𝖨" },
+ ["sf J"] = { true, "𝖩" },
+ ["sf K"] = { true, "𝖪" },
+ ["sf L"] = { true, "𝖫" },
+ ["sf M"] = { true, "𝖬" },
+ ["sf N"] = { true, "𝖭" },
+ ["sf O"] = { true, "𝖮" },
+ ["sf P"] = { true, "𝖯" },
+ ["sf Q"] = { true, "𝖰" },
+ ["sf R"] = { true, "𝖱" },
+ ["sf S"] = { true, "𝖲" },
+ ["sf T"] = { true, "𝖳" },
+ ["sf U"] = { true, "𝖴" },
+ ["sf V"] = { true, "𝖵" },
+ ["sf W"] = { true, "𝖶" },
+ ["sf X"] = { true, "𝖷" },
+ ["sf Y"] = { true, "𝖸" },
+ ["sf Z"] = { true, "𝖹" },
+
+ -- monospace
+
+ ["tt a"] = { true, "𝚊" },
+ ["tt b"] = { true, "𝚋" },
+ ["tt c"] = { true, "𝚌" },
+ ["tt d"] = { true, "𝚍" },
+ ["tt e"] = { true, "𝚎" },
+ ["tt f"] = { true, "𝚏" },
+ ["tt g"] = { true, "𝚐" },
+ ["tt h"] = { true, "𝚑" },
+ ["tt i"] = { true, "𝚒" },
+ ["tt j"] = { true, "𝚓" },
+ ["tt k"] = { true, "𝚔" },
+ ["tt l"] = { true, "𝚕" },
+ ["tt m"] = { true, "𝚖" },
+ ["tt n"] = { true, "𝚗" },
+ ["tt o"] = { true, "𝚘" },
+ ["tt p"] = { true, "𝚙" },
+ ["tt q"] = { true, "𝚚" },
+ ["tt r"] = { true, "𝚛" },
+ ["tt s"] = { true, "𝚜" },
+ ["tt t"] = { true, "𝚝" },
+ ["tt u"] = { true, "𝚞" },
+ ["tt v"] = { true, "𝚟" },
+ ["tt w"] = { true, "𝚠" },
+ ["tt x"] = { true, "𝚡" },
+ ["tt y"] = { true, "𝚢" },
+ ["tt z"] = { true, "𝚣" },
+
+ ["tt A"] = { true, "𝙰" },
+ ["tt B"] = { true, "𝙱" },
+ ["tt C"] = { true, "𝙲" },
+ ["tt D"] = { true, "𝙳" },
+ ["tt E"] = { true, "𝙴" },
+ ["tt F"] = { true, "𝙵" },
+ ["tt G"] = { true, "𝙶" },
+ ["tt H"] = { true, "𝙷" },
+ ["tt I"] = { true, "𝙸" },
+ ["tt J"] = { true, "𝙹" },
+ ["tt K"] = { true, "𝙺" },
+ ["tt L"] = { true, "𝙻" },
+ ["tt M"] = { true, "𝙼" },
+ ["tt N"] = { true, "𝙽" },
+ ["tt O"] = { true, "𝙾" },
+ ["tt P"] = { true, "𝙿" },
+ ["tt Q"] = { true, "𝚀" },
+ ["tt R"] = { true, "𝚁" },
+ ["tt S"] = { true, "𝚂" },
+ ["tt T"] = { true, "𝚃" },
+ ["tt U"] = { true, "𝚄" },
+ ["tt V"] = { true, "𝚅" },
+ ["tt W"] = { true, "𝚆" },
+ ["tt X"] = { true, "𝚇" },
+ ["tt Y"] = { true, "𝚈" },
+ ["tt Z"] = { true, "𝚉" },
+
+ -- some more undocumented
+
+ ["dx"] = { false, { "d", "x" } }, -- "{dx}" "\\left(dx\\right)"
+ ["dy"] = { false, { "d", "y" } }, -- "{dy}" "\\left(dy\\right)"
+ ["dz"] = { false, { "d", "z" } }, -- "{dz}" "\\left(dz\\right)"
+
+ -- fences
+
+ ["(:"] = { true, "(:" },
+ ["{:"] = { true, "{:" },
+ ["[:"] = { true, "[:" },
+ ["("] = { true, "(" },
+ ["["] = { true, "[" },
+ ["{"] = { true, "{" },
+ ["<<"] = { true, "⟨" }, -- why not <:
+ ["|_"] = { true, "⌊" },
+ ["|~"] = { true, "⌈" },
+ ["⟨"] = { true, "⟨" },
+ ["〈"] = { true, "⟨" },
+ ["〈"] = { true, "⟨" },
+
+ [":)"] = { true, ":)" },
+ [":}"] = { true, ":}" },
+ [":]"] = { true, ":]" },
+ [")"] = { true, ")" },
+ ["]"] = { true, "]" },
+ ["}"] = { true, "}" },
+ [">>"] = { true, "⟩" }, -- why not :>
+ ["~|"] = { true, "⌉" },
+ ["_|"] = { true, "⌋" },
+ ["⟩"] = { true, "⟩" },
+ ["〉"] = { true, "⟩" },
+ ["〉"] = { true, "⟩" },
+
+ ["lparent"] = { true, "(" },
+ ["lbracket"] = { true, "[" },
+ ["lbrace"] = { true, "{" },
+ ["langle"] = { true, "⟨" },
+ ["lfloor"] = { true, "⌊" },
+ ["lceil"] = { true, "⌈" },
+
+ ["rparent"] = { true, ")" },
+ ["rbracket"] = { true, "]" },
+ ["rbrace"] = { true, "}" },
+ ["rangle"] = { true, "⟩" },
+ ["rfloor"] = { true, "⌋" },
+ ["rceil"] = { true, "⌉" },
+
+ -- a bit special:
+
+-- ["\\frac"] = { true, "frac" },
+
+ -- now it gets real crazy, only these two:
+
+ ["&gt;"] = { true, ">" },
+ ["&lt;"] = { true, "<" },
+
+ -- extra:
+
+ -- also, invisible times
+
+ ["dd"] = { false, "{\\tf d}" },
+ ["ee"] = { false, "{\\tf e}" },
+ ["xxx"] = { true, utfchar(0x2063) }, -- invisible times
+
+}
+
+-- a..z A..Z : allemaal op italic alphabet
+-- en dan default naar upright "upr a"
+
+for k, v in next, characters.data do
+ local name = v.mathname
+ if name and not reserved[name] then
+ local char = { true, utfchar(k) }
+ reserved[ name] = char
+ -- reserved["\\" .. name] = char
+ end
+ -- local spec = v.mathspec
+ -- if spec then
+ -- for i=1,#spec do
+ -- local name = spec[i].name
+ -- if name and not reserved[name] then
+ -- reserved[name] = { true, utfchar(k) }
+ -- end
+ -- end
+ -- end
+end
+
+reserved.P = nil
+reserved.S = nil
+
+local isbinary = {
+ ["\\frac"] = true,
+ ["\\root"] = true,
+ ["\\asciimathroot"] = true,
+ ["\\asciimathstackrel"] = true,
+}
+
+local isunary = { -- can be taken from reserved
+ ["\\sqrt"] = true,
+ ["\\asciimathsqrt"] = true,
+ ["\\text"] = true, -- mathoptext
+ ["\\mathoptext"] = true, -- mathoptext
+ ["\\asciimathoptext"] = true, -- mathoptext
+ ["\\hat"] = true, -- widehat
+ ["\\widehat"] = true, -- widehat
+ ["\\bar"] = true, --
+ ["\\overbar"] = true, --
+ ["\\underline"] = true, --
+ ["\\vec"] = true, -- overrightarrow
+ ["\\overrightarrow"] = true, -- overrightarrow
+ ["\\dot"] = true, --
+ ["\\ddot"] = true, --
+
+}
+
+local isfunny = {
+ ["\\sin"] = true,
+}
+
+local isinfix = {
+ ["^"] = true,
+ ["_"] = true,
+}
+
+local isstupid = {
+ ["\\prod"] = true,
+ ["\\sinh"] = true,
+ ["\\cosh"] = true,
+ ["\\tanh"] = true,
+ ["\\sum"] = true,
+ ["\\int"] = true,
+ ["\\sin"] = true,
+ ["\\cos"] = true,
+ ["\\tan"] = true,
+ ["\\csc"] = true,
+ ["\\sec"] = true,
+ ["\\cot"] = true,
+ ["\\log"] = true,
+ ["\\det"] = true,
+ ["\\lim"] = true,
+ ["\\mod"] = true,
+ ["\\gcd"] = true,
+ ["\\min"] = true,
+ ["\\max"] = true,
+ ["\\ln"] = true,
+
+ ["\\atan"] = true,
+ ["\\acos"] = true,
+ ["\\asin"] = true,
+ true,
+ ["\\arctan"] = true,
+ ["\\arccos"] = true,
+ ["\\arcsin"] = true,
+
+ ["f"] = true,
+ ["g"] = true,
+}
+
+local isleft = {
+ [s_lparent] = true,
+ [s_lbrace] = true,
+ [s_lbracket] = true,
+ [s_langle] = true,
+ [s_lfloor] = true,
+ [s_lceil] = true,
+ [s_left] = true,
+}
+
+local isright = {
+ [s_rparent] = true,
+ [s_rbrace] = true,
+ [s_rbracket] = true,
+ [s_rangle] = true,
+ [s_rfloor] = true,
+ [s_rceil] = true,
+ [s_right] = true,
+}
+
+local issimplified = {
+}
+
+--
+
+-- special mess
+
+local d_one = R("09")
+local d_two = d_one * d_one
+local d_three = d_two * d_one
+local d_four = d_three * d_one
+local d_split = P(-1) + Carg(2) * (S(".") /"")
+
+local d_spaced = (Carg(1) * d_three)^1
+
+local digitized_1 = Cs ( (
+ d_three * d_spaced * d_split +
+ d_two * d_spaced * d_split +
+ d_one * d_spaced * d_split +
+ P(1)
+ )^1 )
+
+local p_fourbefore = d_four * d_split
+local p_fourafter = d_four * P(-1)
+
+local p_beforecomma = d_three * d_spaced^0 * d_split
+ + d_two * d_spaced^0 * d_split
+ + d_one * d_spaced^0 * d_split
+ + d_one * d_split
+
+local p_aftercomma = p_fourafter
+ + d_three * d_spaced
+ + d_two * d_spaced
+ + d_one * d_spaced
+
+local digitized_2 = Cs (
+ p_fourbefore * (p_aftercomma^0) +
+ p_beforecomma * ((p_aftercomma + d_one^1)^0)
+ )
+
+local p_fourbefore = d_four * d_split
+local p_fourafter = d_four
+local d_spaced = (Carg(1) * (d_three + d_two + d_one))^1
+local p_aftercomma = p_fourafter * P(-1)
+ + d_three * d_spaced * P(1)^0
+ + d_one^1
+
+-- local digitized_3 = Cs (
+-- p_fourbefore * p_aftercomma^0 +
+-- p_beforecomma * p_aftercomma^0
+-- )
+
+local digitized_3 = Cs((p_fourbefore + p_beforecomma) * p_aftercomma^0)
+
+local splitmethods = {
+ digitized_1,
+ digitized_2,
+ digitized_3,
+}
+
+local splitmethod = nil
+local symbolmethod = nil
+local digitseparator = utfchar(0x2008)
+local digitsymbol = "."
+
+function asciimath.setup(settings)
+ splitmethod = splitmethods[tonumber(settings.splitmethod) or 0]
+ if splitmethod then
+ digitsymbol = settings.symbol
+ if not digitsymbol or digitsymbol == "" then
+ digitsymbol = "."
+ end
+ local separator = settings.separator
+ if separator == true or not interfaces or interfaces.variables.yes then
+ digitseparator = utfchar(0x2008)
+ elseif type(separator) == "string" and separator ~= "" then
+ digitseparator = separator
+ else
+ splitmethod = nil
+ end
+ if digitsymbol ~= "." then
+ symbolmethod = lpeg.replacer(".",digitsymbol)
+ else
+ symbolmethod = nil
+ end
+ end
+end
+
+local collected_digits = { }
+local collected_filename = "asciimath-digits.lua"
+
+function numbermess(s)
+ if splitmethod then
+ local d = lpegmatch(splitmethod,s,1,digitseparator,digitsymbol)
+ if not d and symbolmethod then
+ d = lpegmatch(symbolmethod,s)
+ end
+ if d then
+ if trace_digits and s ~= d then
+ collected_digits[s] = d
+ end
+ return d
+ end
+ end
+ return s
+end
+
+-- asciimath.setup { splitmethod = 3, symbol = "," }
+-- local t = {
+-- "0.00002",
+-- "1", "12", "123", "1234", "12345", "123456", "1234567", "12345678", "123456789",
+-- "1.1",
+-- "12.12",
+-- "123.123",
+-- "1234.123",
+-- "1234.1234",
+-- "12345.1234",
+-- "1234.12345",
+-- "12345.12345",
+-- "123456.123456",
+-- "1234567.1234567",
+-- "12345678.12345678",
+-- "123456789.123456789",
+-- "0.1234",
+-- "1234.0",
+-- "1234.00",
+-- "0.123456789",
+-- "100.00005",
+-- "0.80018",
+-- "10.80018",
+-- "100.80018",
+-- "1000.80018",
+-- "10000.80018",
+-- }
+-- for i=1,#t do print(formatters["%-20s : [%s]"](t[i],numbermess(t[i]))) end
+
+statistics.register("asciimath",function()
+ if trace_digits then
+ local n = table.count(collected_digits)
+ if n > 0 then
+ table.save(collected_filename,collected_digits)
+ return string.format("%s digit conversions saved in %s",n,collected_filename)
+ else
+ os.remove(collected_filename)
+ end
+ end
+end)
+
+local p_number_base = patterns.cpnumber or patterns.cnumber or patterns.number
+local p_number = C(p_number_base)
+----- p_number = p_number_base
+local p_spaces = patterns.whitespace
+
+local p_utf_base = patterns.utf8character
+local p_utf = C(p_utf_base)
+-- local p_entity = (P("&") * C((1-P(";"))^2) * P(";"))/ entities
+
+-- entities["gt"] = ">"
+-- entities["lt"] = "<"
+-- entities["amp"] = "&"
+-- entities["dquot"] = '"'
+-- entities["quot"] = "'"
+
+local p_onechar = p_utf_base * P(-1)
+
+----- p_number = Cs((patterns.cpnumber or patterns.cnumber or patterns.number)/function(s) return (gsub(s,",","{,}")) end)
+
+local sign = P("-")^-1
+local digits = R("09")^1
+local integer = sign * digits
+local real = digits * (S(".") * digits)^-1
+local float = real * (P("E") * integer)^-1
+
+-- local number = C(float + integer)
+-- local p_number = C(float)
+local p_number = float / numbermess
+
+local k_reserved = sortedkeys(reserved)
+local k_commands = { }
+local k_unicode = { }
+
+asciimath.keys = {
+ reserved = k_reserved
+}
+
+local k_reserved_different = { }
+local k_reserved_words = { }
+
+for k, v in sortedhash(reserved) do
+ local replacement = v[2]
+ if v[1] then
+ k_unicode[k] = replacement
+ else
+ k_unicode[k] = k -- keep them ... later we remap these
+ if k ~= replacement then
+ k_reserved_different[#k_reserved_different+1] = k
+ end
+ end
+ if find(k,"^[a-zA-Z]+$") then
+ k_unicode["\\"..k] = replacement
+ else
+ k_unicode["\\"..k] = k -- dirty trick, no real unicode (still needed ?)
+ end
+ if not find(k,"[^a-zA-Z]") then
+ k_reserved_words[#k_reserved_words+1] = k
+ end
+ k_commands[k] = replacement
+end
+
+local p_reserved =
+ lpeg.utfchartabletopattern(k_reserved_different) / k_commands
+
+local p_unicode =
+-- lpeg.utfchartabletopattern(table.keys(k_unicode)) / k_unicode
+ lpeg.utfchartabletopattern(k_unicode) / k_unicode
+
+local p_texescape = patterns.texescape
+
+local function texescaped(s)
+ return lpegmatch(p_texescape,s) or s
+end
+
+local p_text =
+ P("text")
+ * p_spaces^0
+ * Cc("\\asciimathoptext")
+ * ( -- maybe balanced
+ Cs( P("{") * ((1-P("}"))^0/texescaped) * P("}") )
+ + Cs((P("(")/"{") * ((1-P(")"))^0/texescaped) * (P(")")/"}"))
+ )
+ + Cc("\\asciimathoptext") * Cs(Cc("{") * (C(patterns.undouble)/texescaped) * Cc("}"))
+
+local m_left = {
+ ["(:"] = s_langle,
+ ["{:"] = s_left,
+ ["[:"] = s_left,
+ ["("] = s_lparent,
+ ["["] = s_lbracket,
+ ["{"] = s_lbrace,
+ ["⟨"] = s_langle,
+ ["⌈"] = s_lceil,
+ ["⌊"] = s_lfloor,
+
+ -- ["<<"] = s_langle, -- why not <:
+ -- ["|_"] = s_lfloor,
+ -- ["|~"] = s_lceil,
+ -- ["〈"] = s_langle,
+ -- ["〈"] = s_langle,
+
+ -- ["lparent"] = s_lparent,
+ -- ["lbracket"] = s_lbracket,
+ -- ["lbrace"] = s_lbrace,
+ -- ["langle"] = s_langle,
+ -- ["lfloor"] = s_lfloor,
+ -- ["lceil"] = s_lceil,
+}
+
+local m_right = {
+ [":)"] = s_rangle,
+ [":}"] = s_right,
+ [":]"] = s_right,
+ [")"] = s_rparent,
+ ["]"] = s_rbracket,
+ ["}"] = s_rbrace,
+ ["⟩"] = s_rangle,
+ ["⌉"] = s_rceil,
+ ["⌋"] = s_rfloor,
+
+ -- [">>"] = s_rangle, -- why not :>
+ -- ["~|"] = s_rceil,
+ -- ["_|"] = s_rfloor,
+ -- ["〉"] = s_rangle,
+ -- ["〉"] = s_rangle,
+
+ -- ["rparent"] = s_rparent,
+ -- ["rbracket"] = s_rbracket,
+ -- ["rbrace"] = s_rbrace,
+ -- ["rangle"] = s_rangle,
+ -- ["rfloor"] = s_rfloor,
+ -- ["rceil"] = s_rceil,
+}
+
+local islimits = {
+ ["\\sum"] = true,
+ -- ["∑"] = true,
+ ["\\prod"] = true,
+ -- ["∏"] = true,
+ ["\\lim"] = true,
+}
+
+local p_left =
+ lpeg.utfchartabletopattern(m_left) / m_left
+local p_right =
+ lpeg.utfchartabletopattern(m_right) / m_right
+
+-- special cases
+
+-- local p_special =
+-- C("/")
+-- + P("\\ ") * Cc("{}") * p_spaces^0 * C(S("^_"))
+-- + P("\\ ") * Cc("\\space")
+-- + P("\\\\") * Cc("\\backslash")
+-- + P("\\") * (R("az","AZ")^1/entities)
+-- + P("|") * Cc("\\|")
+--
+-- faster bug also uglier:
+
+local p_special =
+ P("|") * Cc("\\|") -- s_mbar -- maybe always add left / right as in mml ?
+ + P("\\") * (
+ (
+ P(" ") * (
+ Cc("{}") * p_spaces^0 * C(S("^_"))
+ + Cc("\\space")
+ )
+ )
+ + P("\\") * Cc("\\backslash")
+ -- + (R("az","AZ")^1/entities)
+ + C(R("az","AZ")^1)
+ )
+
+-- open | close :: {: | :}
+
+local u_parser = Cs ( (
+ patterns.doublequoted +
+ P("text") * p_spaces^0 * P("(") * (1-P(")"))^0 * P(")") + -- -- todo: balanced
+ P("\\frac") / "frac" + -- bah
+ p_unicode +
+ p_utf_base
+)^0 )
+
+local a_parser = Ct { "tokenizer",
+ tokenizer = (
+ p_spaces
+ + p_number
+ + p_text
+ -- + Ct(p_open * V("tokenizer") * p_close) -- {: (a+b,=,1),(a+b,=,7) :}
+ -- + Ct(p_open * V("tokenizer") * p_close_right) -- { (a+b,=,1),(a+b,=,7) :}
+ -- + Ct(p_open_left * V("tokenizer") * p_right) -- {: (a+b,=,1),(a+b,=,7) }
+ + Ct(p_left * V("tokenizer") * p_right) -- { (a+b,=,1),(a+b,=,7) }
+ + p_special
+ + p_reserved
+ -- + p_utf - p_close - p_right
+ + (p_utf - p_right)
+ )^1,
+}
+
+local collapse = nil
+local serialize = table.serialize
+local f_state = formatters["level %s : %s : intermediate"]
+
+local function show_state(t,level,state)
+ report_asciimath(serialize(t,f_state(level,state)))
+end
+
+local function show_result(original,unicoded,texcoded)
+ report_asciimath("original > %s",original)
+ report_asciimath("unicoded > %s",unicoded)
+ report_asciimath("texcoded > %s",texcoded)
+end
+
+local function collapse_matrices(t)
+ local n = #t
+ if n > 4 and t[3] == "," then
+ local l1 = t[1]
+ local r1 = t[n]
+ if isleft[l1] and isright[r1] then
+ local l2 = t[2]
+ local r2 = t[n-1]
+ if type(l2) == "table" and type(r2) == "table" then
+ -- we have a matrix
+ local valid = true
+ for i=3,n-2,2 do
+ if t[i] ~= "," then
+ valid = false
+ break
+ end
+ end
+ if valid then
+ for i=2,n-1,2 do
+ local ti = t[i]
+ local tl = ti[1]
+ local tr = ti[#ti]
+ if isleft[tl] and isright[tr] then
+ -- ok
+ else
+ valid = false
+ break
+ end
+ end
+ if valid then
+ local omit = l1 == s_left and r1 == s_right
+ if omit then
+ t[1] = "\\startmatrix"
+ else
+ t[1] = l1 .. "\\startmatrix"
+ end
+ for i=2,n-1 do
+ if t[i] == "," then
+ t[i] = "\\NR"
+ else
+ local ti = t[i]
+ ti[1] = "\\NC"
+ for i=2,#ti-1 do
+ if ti[i] == "," then
+ ti[i] = "\\NC"
+ end
+ end
+ ti[#ti] = nil
+ end
+ end
+ if omit then
+ t[n] = "\\NR\\stopmatrix"
+ else
+ t[n] = "\\NR\\stopmatrix" .. r1
+ end
+ end
+ end
+ end
+ end
+ end
+ return t
+end
+
+local function collapse_bars(t)
+ local n, i, l, m = #t, 1, false, 0
+ while i <= n do
+ local current = t[i]
+ if current == "\\|" then
+ if l then
+ m = m + 1
+ t[l] = s_lbar
+ t[i] = s_rbar
+ t[m] = { unpack(t,l,i) }
+ l = false
+ else
+ l = i
+ end
+ elseif not l then
+ m = m + 1
+ t[m] = current
+ end
+ i = i + 1
+ end
+ if l then
+ local tt = { s_lnothing } -- space fools final checker
+ local tm = 1
+ for i=1,m do
+ tm = tm + 1
+ tt[tm] = t[i]
+ end
+ tm = tm + 1
+ tt[tm] = s_mbar
+ for i=l+1,n do
+ tm = tm + 1
+ tt[tm] = t[i]
+ end
+ tm = tm + 1
+ tt[tm] = s_rnothing -- space fools final checker
+ m = tm
+ t = tt
+ elseif m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_pairs(t)
+ local n, i = #t, 1
+ while i < n do
+ local current = t[i]
+ if current == "/" and i > 1 then
+ local tl = t[i-1]
+ local tr = t[i+1]
+ local tn = t[i+2]
+ if type(tl) == "table" then
+ if isleft[tl[1]] and isright[tl[#tl]] then
+ tl[1] = "" -- todo: remove
+ tl[#tl] = nil
+ end
+ end
+ if type(tr) == "table" then
+ if tn == "^" then
+ -- brr 1/(1+x)^2
+ elseif isleft[tr[1]] and isright[tr[#tr]] then
+ tr[1] = "" -- todo: remove
+ tr[#tr] = nil
+ end
+ end
+ i = i + 2
+ elseif current == "," or current == ";" then
+ -- t[i] = current .. "\\thinspace" -- look sbad in (a,b)
+ i = i + 1
+ else
+ i = i + 1
+ end
+ end
+ return t
+end
+
+local function collapse_parentheses(t)
+ local n, i = #t, 1
+ if n > 2 then
+ while i < n do
+ local current = t[i]
+ if type(current) == "table" and isleft[t[i-1]] and isright[t[i+1]] then
+ local c = #current
+ if c > 2 and isleft[current[1]] and isright[current[c]] then
+ remove(current,c)
+ remove(current,1)
+ end
+ i = i + 3
+ else
+ i = i + 1
+ end
+ end
+ end
+ return t
+end
+
+local function collapse_stupids(t)
+ local n, m, i = #t, 0, 1
+ while i <= n do
+ m = m + 1
+ local current = t[i]
+ if isstupid[current] then
+ local one = t[i+1]
+ if type(one) == "table" then
+ one = collapse(one,level)
+ t[m] = current .. "{" .. one .. "}"
+ i = i + 2
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then -- yes?
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_signs(t)
+ local n, m, i = #t, 0, 1
+ while i <= n do
+ m = m + 1
+ local current = t[i]
+ if isunary[current] then
+ local one = t[i+1]
+ if not one then
+-- m = m + 1
+ t[m] = current .. "{}" -- error
+ return t
+-- break
+ end
+ if type(one) == "table" then
+ if isleft[one[1]] and isright[one[#one]] then
+ remove(one,#one)
+ remove(one,1)
+ end
+ one = collapse(one,level)
+ elseif one == "-" and i + 2 <= n then -- or another sign ? or unary ?
+ local t2 = t[i+2]
+ if type(t2) == "string" then
+ one = one .. t2
+ i = i + 1
+ end
+ end
+ t[m] = current .. "{" .. one .. "}"
+ i = i + 2
+ elseif i + 2 <= n and isfunny[current] then
+ local one = t[i+1]
+ if isinfix[one] then
+ local two = t[i+2]
+ if two == "-" then -- or another sign ? or unary ?
+ local three = t[i+3]
+ if three then
+ if type(three) == "table" then
+ three = collapse(three,level)
+ end
+ t[m] = current .. one .. "{" .. two .. three .. "}"
+ i = i + 4
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then -- yes?
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_binaries(t)
+ local n, m, i = #t, 0, 1
+ while i <= n do
+ m = m + 1
+ local current = t[i]
+ if isbinary[current] then
+ local one = t[i+1]
+ local two = t[i+2]
+ if not one then
+ t[m] = current .. "{}{}" -- error
+return t
+-- break
+ end
+ if type(one) == "table" then
+ if isleft[one[1]] and isright[one[#one]] then
+ remove(one,#one)
+ remove(one,1)
+ end
+ one = collapse(one,level)
+ end
+ if not two then
+ t[m] = current .. "{" .. one .. "}{}"
+return t
+-- break
+ end
+ if type(two) == "table" then
+ if isleft[two[1]] and isright[two[#two]] then
+ remove(two,#two)
+ remove(two,1)
+ end
+ two = collapse(two,level)
+ end
+ t[m] = current .. "{" .. one .. "}{" .. two .. "}"
+ i = i + 3
+ else
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then -- yes?
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_infixes_1(t)
+ local n, i = #t, 1
+ while i <= n do
+ local current = t[i]
+ if isinfix[current] then
+ local what = t[i+1]
+ if what then
+ if type(what) == "table" then
+ local f, l = what[1], what[#what]
+ if isleft[f] and isright[l] then
+ remove(what,#what)
+ remove(what,1)
+ end
+ t[i+1] = collapse(what,level) -- collapse ?
+ end
+ i = i + 2
+ else
+ break
+ end
+ else
+ i = i + 1
+ end
+ end
+ return t
+end
+
+function collapse_limits(t)
+ local n, m, i = #t, 0, 1
+ while i <= n do
+ m = m + 1
+ local current = t[i]
+ if islimits[current] then
+ local one, two, first, second = nil, nil, t[i+1], t[i+3]
+ if first and isinfix[first] then
+ one = t[i+2]
+ if one then
+ -- if type(one) == "table" then
+ -- if isleft[one[1]] and isright[one[#one]] then
+ -- remove(one,#one)
+ -- remove(one,1)
+ -- end
+ -- one = collapse(one,level)
+ -- end
+ if second and isinfix[second] then
+ two = t[i+4]
+ -- if type(two) == "table" then
+ -- if isleft[two[1]] and isright[two[#two]] then
+ -- remove(two,#two)
+ -- remove(two,1)
+ -- end
+ -- two = collapse(two,level)
+ -- end
+ end
+ if two then
+ t[m] = current .. "\\limits" .. first .. "{" .. one .. "}" .. second .. "{" .. two .. "}"
+ i = i + 5
+ else
+ t[m] = current .. "\\limits" .. first .. "{" .. one .. "}"
+ i = i + 3
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ else
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then -- yes?
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_tables(t)
+ local n, m, i = #t, 0, 1
+ while i <= n do
+ m = m + 1
+ local current = t[i]
+ if type(current) == "table" then
+ if current[1] == "\\NC" then
+ t[m] = collapse(current,level)
+ else
+ t[m] = "{" .. collapse(current,level) .. "}"
+ end
+ i = i + 1
+ else
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then -- yes?
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_infixes_2(t)
+ local n, m, i = #t, 0, 1
+ while i < n do
+ local current = t[i]
+ if isinfix[current] and i > 1 then
+ local tl = t[i-1]
+ local tr = t[i+1]
+ local ti = t[i+2]
+ local tn = t[i+3]
+ if ti and tn and isinfix[ti] then
+ t[m] = tl .. current .. "{" .. tr .. "}" .. ti .. "{" .. tn .. "}"
+ i = i + 4
+ else
+ t[m] = tl .. current .. "{" .. tr .. "}"
+ i = i + 2
+ end
+ else
+ m = m + 1
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_fractions_1(t)
+ local n, m, i = #t, 0, 1
+ while i < n do
+ local current = t[i]
+ if current == "/" and i > 1 then
+ local tl = t[i-1]
+ local tr = t[i+1]
+ t[m] = "\\frac{" .. tl .. "}{" .. tr .. "}"
+ i = i + 2
+ if i < n then
+ m = m + 1
+ t[m] = t[i]
+ i = i + 1
+ end
+ else
+ m = m + 1
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_fractions_2(t)
+ local n, m, i = #t, 0, 1
+ while i < n do
+ local current = t[i]
+ if current == "⁄" and i > 1 then -- \slash
+ t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. t[i+1] .. s_right .. "}"
+ i = i + 2
+ if i < n then
+ m = m + 1
+ t[m] = t[i]
+ i = i + 1
+ end
+ else
+ m = m + 1
+ t[m] = current
+ i = i + 1
+ end
+ end
+ if i == n then
+ m = m + 1
+ t[m] = t[n]
+ end
+ if m < n then
+ for i=n,m+1,-1 do
+ t[i] = nil
+ end
+ end
+ return t
+end
+
+local function collapse_result(t)
+ local n = #t
+ if t[1] == s_left and t[n] == s_right then -- see bar .. space needed there
+ return concat(t," ",2,n-1)
+ else
+ return concat(t," ")
+ end
+end
+
+collapse = function(t,level)
+ -- check
+ if not t then
+ return ""
+ end
+ -- tracing
+ if trace_detail then
+ if level then
+ level = level + 1
+ else
+ level = 1
+ end
+ show_state(t,level,"parsed")
+ end
+ -- steps
+ t = collapse_matrices (t) if trace_detail then show_state(t,level,"matrices") end
+ t = collapse_bars (t) if trace_detail then show_state(t,level,"bars") end
+t = collapse_stupids (t) if trace_detail then show_state(t,level,"stupids") end
+ t = collapse_pairs (t) if trace_detail then show_state(t,level,"pairs") end
+ t = collapse_parentheses(t) if trace_detail then show_state(t,level,"parentheses") end
+ t = collapse_signs (t) if trace_detail then show_state(t,level,"signs") end
+ t = collapse_binaries (t) if trace_detail then show_state(t,level,"binaries") end
+ t = collapse_infixes_1 (t) if trace_detail then show_state(t,level,"infixes (1)") end
+ t = collapse_limits (t) if trace_detail then show_state(t,level,"limits") end
+ t = collapse_tables (t) if trace_detail then show_state(t,level,"tables") end
+ t = collapse_infixes_2 (t) if trace_detail then show_state(t,level,"infixes (2)") end
+ t = collapse_fractions_1(t) if trace_detail then show_state(t,level,"fractions (1)") end
+ t = collapse_fractions_2(t) if trace_detail then show_state(t,level,"fractions (2)") end
+ -- done
+ return collapse_result(t)
+end
+
+-- todo: cache simple ones, say #str < 10, maybe weak
+
+local context = context
+local ctx_mathematics = context and context.mathematics or report_asciimath
+local ctx_type = context and context.type or function() end
+local ctx_inleft = context and context.inleft or function() end
+
+local function convert(str,totex)
+ local unicoded = lpegmatch(u_parser,str) or str
+ local texcoded = collapse(lpegmatch(a_parser,unicoded))
+ if trace_mapping then
+ show_result(str,unicoded,texcoded)
+ end
+ if totex then
+ ctx_mathematics(texcoded)
+ else
+ return texcoded
+ end
+end
+
+local n = 0
+local p = (
+ (S("{[(") + P("\\left" )) / function() n = n + 1 end
+ + (S("}])") + P("\\right")) / function() n = n - 1 end
+ + p_utf_base
+)^0
+
+local function invalidtex(str)
+ n = 0
+ lpegmatch(p,str)
+ if n == 0 then
+ return false
+ elseif n < 0 then
+ return formatters["too many left fences: %s"](-n)
+ elseif n > 0 then
+ return formatters["not enough right fences: %s"](n)
+ end
+end
+
+local collected = { }
+local indexed = { }
+
+-- bonus
+
+local p_reserved_spaced =
+ C(lpeg.utfchartabletopattern(k_reserved_words)) / " %1 "
+
+local p_text =
+ C(P("text")) / " %1 "
+ * p_spaces^0
+ * ( -- maybe balanced
+ (P("{") * (1-P("}"))^0 * P("}"))
+ + (P("(") * (1-P(")"))^0 * P(")"))
+ )
+ + patterns.doublequoted
+
+local p_expand = Cs((p_text + p_reserved_spaced + p_utf_base)^0)
+local p_compress = patterns.collapser
+
+local function cleanedup(str)
+ return lpegmatch(p_compress,lpegmatch(p_expand,str)) or str
+end
+
+-- so far
+
+local function register(s,cleanedup,collected,shortname)
+ local c = cleanedup(s)
+ local f = collected[c]
+ if f then
+ f.count = f.count + 1
+ f.files[shortname] = (f.files[shortname] or 0) + 1
+ if s ~= c then
+ f.cleanedup = f.cleanedup + 1
+ end
+ f.dirty[s] = (f.dirty[s] or 0) + 1
+ else
+ local texcoded = convert(s)
+ local message = invalidtex(texcoded)
+ if message then
+ report_asciimath("%s: %s : %s",message,s,texcoded)
+ end
+ collected[c] = {
+ count = 1,
+ files = { [shortname] = 1 },
+ texcoded = texcoded,
+ message = message,
+ cleanedup = s ~= c and 1 or 0,
+ dirty = { [s] = 1 }
+ }
+ end
+end
+
+local function wrapup(collected,indexed)
+ local n = 0
+ for k, v in sortedhash(collected) do
+ n = n + 1
+ v.n= n
+ indexed[n] = k
+ end
+end
+
+function collect(fpattern,element,collected,indexed)
+ local element = element or "am"
+ local mpattern = formatters["<%s>(.-)</%s>"](element,element)
+ local filenames = resolvers.findtexfile(fpattern)
+ if filenames and filenames ~= "" then
+ filenames = { filenames }
+ else
+ filenames = dir.glob(fpattern)
+ end
+ local cfpattern = gsub(fpattern,"^%./",lfs.currentdir())
+ local cfpattern = gsub(cfpattern,"\\","/")
+ local wildcard = string.split(cfpattern,"*")[1]
+ if not collected then
+ collected = { }
+ indexed = { }
+ end
+ for i=1,#filenames do
+ filename = gsub(filenames[i],"\\","/")
+ local splitname = (wildcard and wildcard ~= "" and string.split(filename,wildcard)[2]) or filename
+ local shortname = gsub(splitname or file.basename(filename),"^%./","")
+ if shortname == "" then
+ shortname = filename
+ end
+ local fullname = resolvers.findtexfile(filename) or filename
+ if fullname ~= "" then
+ for s in gmatch(io.loaddata(fullname),mpattern) do
+ register(s,cleanedup,collected,shortname)
+ end
+ end
+ end
+ wrapup(collected,indexed)
+ return collected, indexed
+end
+
+function filter(root,pattern,collected,indexed)
+ if not pattern or pattern == "" then
+ pattern = "am"
+ end
+ if not collected then
+ collected = { }
+ indexed = { }
+ end
+ for c in xmlcollected(root,pattern) do
+ register(xmltext(c),cleanedup,collected,xmlinclusion(c) or "" )
+ end
+ wrapup(collected,indexed)
+ return collected, indexed
+end
+
+asciimath.convert = convert
+asciimath.reserved = reserved
+asciimath.collect = collect
+asciimath.filter = filter
+asciimath.invalidtex = invalidtex
+asciimath.cleanedup = cleanedup
+
+-- sin(x) = 1 : 3.3 uncached 1.2 cached , so no real gain (better optimize the converter then)
+
+local uncrapped = {
+ ["%"] = "\\mathpercent",
+ ["&"] = "\\mathampersand",
+ ["#"] = "\\mathhash",
+ ["$"] = "\\mathdollar",
+ ["^"] = "\\Hat{\\enspace}", -- terrible hack ... tex really does it sbest to turn any ^ into a superscript
+ ["_"] = "\\underline{\\enspace}",
+}
+
+local function convert(str,nowrap)
+ if #str > 0 then
+ local unicoded = lpegmatch(u_parser,str) or str
+ if lpegmatch(p_onechar,unicoded) then
+ ctx_mathematics(uncrapped[unicoded] or unicoded)
+ else
+ local texcoded = collapse(lpegmatch(a_parser,unicoded))
+ if trace_mapping then
+ show_result(str,unicoded,texcoded)
+ end
+ if #texcoded == 0 then
+ report_asciimath("error in asciimath: %s",str)
+ else
+ local message = invalidtex(texcoded)
+ if message then
+ report_asciimath("%s: %s : %s",message,str,texcoded)
+ ctx_type(formatters["<%s>"](message))
+ elseif nowrap then
+ context(texcoded)
+ else
+ ctx_mathematics(texcoded)
+ end
+ end
+ end
+ end
+end
+
+local context = context
+
+if not context then
+
+-- trace_mapping = true
+-- trace_detail = true
+
+-- report_asciimath(cleanedup([[ac+sinx+xsqrtx+sinsqrtx+sinsqrt(x)]]))
+-- report_asciimath(cleanedup([[a "αsinsqrtx" b]]))
+-- convert([[a "αsinsqrtx" b]])
+-- report_asciimath(cleanedup([[a "α" b]]))
+-- report_asciimath(cleanedup([[//4]]))
+
+-- convert("leq\\leq")
+-- convert([[\^{1/5}log]])
+-- convert("sqrt")
+-- convert("^")
+
+-- convert[[\frac{a}{b}]]
+-- convert[[frac{a}{b}]]
+
+-- convert("frac{a}{b}")
+-- convert("\\sin{a}{b}")
+-- convert("sin{a}{b}")
+-- convert("1: rightarrow")
+-- convert("2: \\rightarrow")
+
+-- convert("((1,2,3),(4,5,6),(7,8,9))")
+
+-- convert("1/(t+x)^2")
+
+-- convert("AA a > 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b")
+-- convert("AA a &gt; 0 ^^ b > 0 | {:log_g:} a + {:log_g:} b")
+
+-- convert("10000,00001")
+-- convert("4/18*100text(%)~~22,2")
+-- convert("4/18*100text(%)≈22,2")
+-- convert("62541/(197,6)≈316,05")
+
+-- convert([[sum x]])
+-- convert([[sum^(1)_(2) x]])
+-- convert([[lim_(1)^(2) x]])
+-- convert([[lim_(1) x]])
+-- convert([[lim^(2) x]])
+
+-- convert([[{: rangle]])
+-- convert([[\langle\larr]])
+-- convert([[langlelarr]])
+-- convert([[D_f=[0 ,→〉]])
+-- convert([[ac+sinx+xsqrtx]])
+-- convert([[ac+\alpha x+xsqrtx-cc b*pi**psi-3alephx / bb X]])
+-- convert([[ac+\ ^ x+xsqrtx]])
+-- convert([[d/dx(x^2+1)]])
+-- convert([[a "αsinsqrtx" b]])
+-- convert([[a "α" b]])
+-- convert([[//4]])
+-- convert([[ {(a+b,=,1),(a+b,=,7)) ]])
+
+-- convert([[ 2/a // 5/b = (2 b) / ( a b) // ( 5 a ) / ( a b ) = (2 b ) / ( 5 a ) ]])
+-- convert([[ (2+x)/a // 5/b ]])
+
+-- convert([[ ( 2/a ) // ( 5/b ) = ( (2 b) / ( a b) ) // ( ( 5 a ) / ( a b ) ) = (2 b ) / ( 5 a ) ]])
+
+-- convert([[ (x/y)^3 = x^3/y^3 ]])
+
+-- convert([[ {: (1,2) :} ]])
+-- convert([[ {: (a+b,=,1),(a+b,=,7) :} ]])
+-- convert([[ { (a+b,=,1),(a+b,=,7) :} ]])
+-- convert([[ {: (a+b,=,1),(a+b,=,7) } ]])
+-- convert([[ { (a+b,=,1),(a+b,=,7) } ]])
+
+-- convert([[(1,5 ±sqrt(1,25 ),0 )]])
+-- convert([[1//2]])
+-- convert([[(p)/sqrt(p)]])
+-- convert([[u_tot]])
+-- convert([[u_tot=4,4 L+0,054 T]])
+
+-- convert([[ [←;0,2] ]])
+-- convert([[ [←;0,2⟩ ]])
+-- convert([[ ⟨←;0,2 ) ]])
+-- convert([[ ⟨←;0,2 ] ]])
+-- convert([[ ⟨←;0,2⟩ ]])
+
+-- convert([[ x^2(x-1/16)=0 ]])
+-- convert([[ y = ax + 3 - 3a ]])
+-- convert([[ y= ((1/4)) ^x ]])
+-- convert([[ x=\ ^ (1/4) log(0 ,002 )= log(0,002) / (log(1/4) ]])
+-- convert([[ x=\ ^glog(y) ]])
+-- convert([[ x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x)) ]])
+-- convert([[ x^2(10 -x)&gt;2 x^2 ]])
+-- convert([[ x^4&gt;x ]])
+
+ return
+
+end
+
+interfaces.implement {
+ name = "asciimath",
+ actions = convert,
+ arguments = "string"
+}
+
+interfaces.implement {
+ name = "justasciimath",
+ actions = convert,
+ arguments = { "string", true },
+}
+
+local ctx_typebuffer = context.typebuffer
+local ctx_mathematics = context.mathematics
+local ctx_color = context.color
+
+local sequenced = table.sequenced
+local assign_buffer = buffers.assign
+
+local show = { }
+asciimath.show = show
+
+local collected, indexed, ignored = { }, { }, { }
+
+local color = { "darkred" }
+
+function show.ignore(n)
+ if type(n) == "string" then
+ local c = collected[n]
+ n = c and c.n
+ end
+ if n then
+ ignored[n] = true
+ end
+end
+
+function show.count(n,showcleanedup)
+ local v = collected[indexed[n]]
+ local count = v.count
+ local cleanedup = v.cleanedup
+ if not showcleanedup or cleanedup == 0 then
+ context(count)
+ elseif count == cleanedup then
+ ctx_color(color,count)
+ else
+ context("%s+",count-cleanedup)
+ ctx_color(color,cleanedup)
+ end
+end
+
+local h = { }
+local am = { "am" }
+
+function show.nofdirty(n)
+ local k = indexed[n]
+ local v = collected[k]
+ local n = v.cleanedup
+ h = { }
+ if n > 0 then
+ for d, n in sortedhash(v.dirty) do
+ if d ~= k then
+ h[#h+1] = { d, n }
+ end
+ end
+ end
+ context(#h)
+end
+
+function show.dirty(m,wrapped)
+ local d = h[m]
+ if d then
+ ctx_inleft(d[2])
+ if wrapped then
+ assign_buffer("am",'"' .. d[1] .. '"')
+ else
+ assign_buffer("am",d[1])
+ end
+ ctx_typebuffer(am)
+ end
+end
+
+function show.files(n)
+ context(sequenced(collected[indexed[n]].files," "))
+end
+
+function show.input(n,wrapped)
+ if wrapped then
+ assign_buffer("am",'"' .. indexed[n] .. '"')
+ else
+ assign_buffer("am",indexed[n])
+ end
+ ctx_typebuffer(am)
+end
+
+function show.result(n)
+ local v = collected[indexed[n]]
+ if ignored[n] then
+ context("ignored")
+ elseif v.message then
+ ctx_color(color, v.message)
+ else
+ ctx_mathematics(v.texcoded)
+ end
+end
+
+function show.load(str,element)
+ collected, indexed, ignored = { }, { }, { }
+ local t = utilities.parsers.settings_to_array(str)
+ for i=1,#t do
+ asciimath.collect(t[i],element or "am",collected,indexed)
+ end
+end
+
+function show.filter(id,element)
+ collected, indexed, ignored = { }, { }, { }
+ asciimath.filter(lxml.getid(id),element or "am",collected,indexed)
+end
+
+function show.max()
+ context(#indexed)
+end
+
+function show.statistics()
+ local usedfiles = { }
+ local noffiles = 0
+ local nofokay = 0
+ local nofbad = 0
+ local nofcleanedup = 0
+ for k, v in next, collected do
+ if ignored[v.n] then
+ nofbad = nofbad + v.count
+ elseif v.message then
+ nofbad = nofbad + v.count
+ else
+ nofokay = nofokay + v.count
+ end
+ nofcleanedup = nofcleanedup + v.cleanedup
+ for k, v in next, v.files do
+ local u = usedfiles[k]
+ if u then
+ usedfiles[k] = u + 1
+ else
+ noffiles = noffiles + 1
+ usedfiles[k] = 1
+ end
+ end
+ end
+ local NC = context.NC
+ local NR = context.NR
+ local EQ = context.EQ
+ context.starttabulate { "|B||" }
+ NC() context("files") EQ() context(noffiles) NC() NR()
+ NC() context("formulas") EQ() context(nofokay+nofbad) NC() NR()
+ NC() context("uniques") EQ() context(#indexed) NC() NR()
+ NC() context("cleanedup") EQ() context(nofcleanedup) NC() NR()
+ NC() context("errors") EQ() context(nofbad) NC() NR()
+ context.stoptabulate()
+end
+
+function show.save(name)
+ table.save(name ~= "" and name or "dummy.lua",collected)
+end
diff --git a/tex/context/modules/mkiv/x-asciimath.mkiv b/tex/context/modules/mkiv/x-asciimath.mkiv
new file mode 100644
index 000000000..d3a629c81
--- /dev/null
+++ b/tex/context/modules/mkiv/x-asciimath.mkiv
@@ -0,0 +1,436 @@
+%D \module
+%D [ file=x-asciimath,
+%D version=2014.06.01, % 2006.04.24, % 1999.11.06,
+%D title=\CONTEXT\ Modules,
+%D subtitle=AsciiMath,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\registerctxluafile{x-asciimath}{}
+
+%D When the Math4All project started, we immediately started using content \MATHML.
+%D Because in school math there is often a reference to calculator input, we also
+%D provided what we called \quote {calcmath}: a predictable expression based way
+%D entering math. At some point \OPENMATH\ was also used but that was later
+%D abandoned because editing is more cumbersome.
+%D
+%D Due to limitations in the web variant (which is independent of rendering for
+%D paper but often determines the coding of document, not seldom for the worse) the
+%D switch was made to presentational \MATHML. But even that proved to be too complex
+%D for rendering on the web, so it got converted to so called \ASCIIMATH\ which
+%D can be rendered using some \JAVASCRIPT\ magic. However, all the formulas (and
+%D we're talking of tens of thousands of them) were very precisely coded by the main
+%D author. Because in intermediate stages of the editing (by additional authors) a
+%D mixture of \MATHML\ and \ASCIIMATH\ was used, we wrote the first version of this
+%D module. As reference we took \url
+%D {http://www1.chapman.edu/~jipsen/mathml/asciimath.html} and. The idea was to
+%D stick to \MATHML\ as reference and if needed use \ASCIIMATH\ as annotation.
+%D
+%D Eventually we ended up with supporting several math encodings in \CONTEXT\ that
+%D could be used mixed: content \MATHML\ (preferred), presentation \MATHML\ (often
+%D messy), \OPENMATH\ (somewhat minimalistic) calcmath (handy for students who are
+%D accustomed to calculators), \ASCIIMATH\ (to make web support easier) and of
+%D course \TEX.
+%D
+%D The first version had some limitations as we didn't want to support all quirks of
+%D \ASCIIMATH\ and also because I was not really in the mood to write a complex parser
+%D when a bit of sane coding can work equally well. Some comments from that version:
+%D
+%D \startnarrower
+%D \startitemize
+%D \item We support only the syntactically clear variants and as long as lpeg does
+%D not support left recursion this is as far as we want to go.
+%D \item The parser is rather insensitive for spaces but yet the advice is to avoid
+%D weird coding like \type {d/dxf(x)} but use \type {d/dx f(x)} instead. After
+%D all we're not in a compact coding cq.\ parser challenge.
+%D \item We also don't support the somewhat confusing \type {sqrt sqrt 2} nor \type
+%D {root3x} (although the second one kind of works). A bit of defensive coding
+%D does not hurt.
+%D \item We can process \type {a/b/c/d} but it's not compatible with the default
+%D behaviour of \ASCIIMATH. Use grouping instead. Yes, we do support the somewhat
+%D nonstandard grouping token mix.
+%D \item You should use explicit \type {text(..)} directives as one can never be sure
+%D what is a reserved word and not.
+%D \stopitemize
+%D
+%D Actually, as the only parsing sensitive elements of \TEX\ are fractions (\type {\over}
+%D and friends, a restricted use of \TEX\ coding is probably as comprehensive and
+%D parsable. The webpage with examples served as starting point so anything beyond
+%D what can be found there isn't supported.
+%D \stopnarrower
+%D
+%D Then in 2014 something bad happened. Following the fashion of minimal encoding
+%D (which of course means messy encoding of complex cases and which can make authors
+%D sloppy too) the web based support workflow of the mentioned project ran into some
+%D limitations and magically one day all carefully coded \MATHML\ was converted into
+%D \ASCIIMATH. As there was no way to recover the original thousands of files and
+%D tens of thousands of formulas we were suddenly stuck with \ASCIIMATH. Because the
+%D conversion had be done automagically, we also saw numerous errors and were forced
+%D to come up with some methods to check formulas. Because \MATHML\ poses some
+%D restrictions it has predictable rendering; \ASCIIMATH\ on the other hand enforces
+%D no structure. Also, because \MATHML\ has to be valid \XML\ it always processes.
+%D Of course, during the decade that the project had run we also had to built in
+%D some catches for abuse but at least we had a relatively stable and configurable
+%D subsystem. So, in order to deal with less predictable cases as well as extensive
+%D checking, a new \ASCIIMATH\ parser was written, one that could also be used to
+%D trace bad coding.
+%D
+%D Because the formal description is incomplete, and because some links to resources
+%D are broken, and because some testing on the web showed that sequences of characters
+%D are interpreted that were not mentioned anywhere (visible), and because we noticed
+%D that the parser was dangerously tolerant, the new code is quite different from the
+%D old code.
+%D
+%D One need to keep in mind that because spaces are optional, the only robust way to
+%D edit \ASCIIMATH\ is to use a \WYSIWYG\ editor and hope that the parser doesn't
+%D change ever. Keys are picked up from spaceless sequences and when not recognized
+%D a (sequence) of characters is considered to be variables. So, \type {xsqrtx} is
+%D valid and renders as \type {$x\sqrt{x}$}, \type {xx} becomes \type {×} (times)
+%D but \type {ac} becomes \type {$a c$} (a times c). We're lucky that \type {AC} is
+%D not turned into Alternating Current, but who knows what happens a few years from
+%D now. So, we do support this spaceless mess, but users are warned: best use a
+%D spacy sequence. The extra amount of spaces (at one byte each) an author has to
+%D include in his|/|her active writing time probably stays below the size of one
+%D holiday picture. Another complication is that numbers (in Dutch) use commas instead
+%D of periods, but vectors use commas as well. We also hav esome different names for
+%D functions which then can conflict with the expectations about collapsed variables.
+%D
+%D It must be noted that simplified encodings (that seem to be the fashion today)
+%D can demand from applications to apply fuzzy logic to make something work out
+%D well. Because we have sequential data that gets rendered, sometimes wrong input
+%D gets obscured simply by the rendering: like the comma's in numbers as well as
+%D for separators (depending on space usage), or plain wrong symbols that somehow
+%D get a representation anyway. This in itself is more a side effect of trying to
+%D use the simplified encoding without applying rules (in the input) or to use it
+%D beyong its intended usage, which then of course can lead to adapted parsers and
+%D catches that themselves trigger further abuse. Imagine that instead of developing
+%D new cars, planes, space ships, mobile phones, computers we would have adapted
+%D horse cars, kites, firework, old fashioned phones and mechanical calculators in a
+%D similar way: patch upon patch of traditional means for sure would not have
+%D worked. So, when you use \ASCIIMATH\ best check immediately how it gets rendered
+%D in the browser as well as on paper. And be prepared to check the more complex
+%D code in the future again. We don't offer any guarantees but of course will try to
+%D keep up.
+%D
+%D In retrospect I sometimes wonder if the energy put into constantly adapting to
+%D the fashion of the day pays off. Probably not. It definitely doesn't pay of.
+%D
+%D More complex crap:
+%D
+%D 1: $x + \stackrel{comment}{\stackrel{\utfchar{"23DE}}{yyyyyyyy}} = y$ \blank
+%D 2: \asciimath{x + stackrel{\utfchar{"23DE}}{yyyyyyyy} = y} \blank
+%D 3: \asciimath{x + stackrel{yyyyyyyy}{\utfchar{"23DE}} = y} \blank
+%D 4: \asciimath{x + stackrel{"comment"}{stackrel{\utfchar{"23DE}}{yyyyyyyy}} = y} \blank
+
+\usemodule[mathml-basics]
+
+\startmodule[asciimath]
+
+\unprotect
+
+\writestatus{asciimath}{beware, this is an experimental (m4all only) module}
+
+%D Hacks:
+
+\unexpanded\def\asciimathoptext #1{\ifmmode\mathoptext{#1}\else#1\fi}
+\unexpanded\def\asciimathoptexttraced #1{\ifmmode\mathoptext{\color[darkgreen]{#1}}\else\color[darkgreen]{#1}\fi}
+\unexpanded\def\asciimathstackrel #1#2{\mathematics{\mathop{\let\limits\relax\mover{#2}{#1}}}}
+\unexpanded\def\asciimathroot #1#2{\sqrt[#1]{#2}}
+\unexpanded\def\asciimathsqrt #1{\sqrt{#1}}
+
+%D The core commands:
+
+% if we need to set
+
+\installsetuponlycommandhandler {asciimath} {asciimath}
+
+\appendtoks
+ \ctxlua{moduledata.asciimath.setup {
+ splitmethod = "\asciimathparameter\c!splitmethod",
+ separator = "\asciimathparameter\c!separator",
+ symbol = "\asciimathparameter\c!symbol",
+ }}%
+\to \everysetupasciimath
+
+\newtoks\everyasciimath
+
+% \appendtoks
+% \ignorediscretionaries
+% \to \everyasciimath
+
+\appendtoks
+ \enableautofences
+\to \everyasciimath
+
+\unexpanded\def\asciimath
+ {\doifnextoptionalelse\asciimath_yes\asciimath_nop}
+
+\def\asciimath_yes[#1]#2%
+ {\mathematics
+ [#1]%
+ {\the\everyasciimath%
+ \clf_justasciimath{\detokenize\expandafter{\normalexpanded{#2}}}}}
+
+\def\asciimath_nop#1%
+ {\mathematics
+ {\the\everyasciimath
+ \clf_justasciimath{\detokenize\expandafter{\normalexpanded{#1}}}}}
+
+\unexpanded\def\ctxmoduleasciimath#1%
+ {\ctxlua{moduledata.asciimath.#1}}
+
+%D Some tracing commands. Using tex commands is 10\% slower that directly piping
+%D from \LUA, but this is non|-|critical code.
+
+\unexpanded\def\ShowAsciiMathLoad [#1]{\ctxlua{moduledata.asciimath.show.load("#1")}}
+\unexpanded\def\ShowAsciiMathIgnore[#1]{\ctxlua{moduledata.asciimath.show.ignore("#1")}}
+\unexpanded\def\ShowAsciiMathXML #1#2{\ctxlua{moduledata.asciimath.show.filter("#1","#2")}}
+\unexpanded\def\ShowAsciiMathStats {\ctxlua{moduledata.asciimath.show.statistics()}}
+\unexpanded\def\ShowAsciiMathMax {\ctxlua{moduledata.asciimath.show.max()}}
+
+\unexpanded\def\ShowAsciiMathResult#1%
+ {\begingroup
+ \blank
+ % if we are in vmode, we don't get positions i.e. a smaller tuc file
+ \inleft{\ttbf#1\hfill\ctxlua{moduledata.asciimath.show.count(#1,true)}}%
+ \dontleavehmode
+ \begingroup
+ \ttbf
+ \ctxlua{moduledata.asciimath.show.files(#1)}
+ \endgroup
+ \blank[medium,samepage]
+ \startcolor[darkblue]
+ \ctxlua{moduledata.asciimath.show.input(#1,true)}
+ \stopcolor
+ \blank[medium,samepage]
+ \doifmode{asciimath:show:dirty} {
+ \dorecurse{\ctxlua{moduledata.asciimath.show.nofdirty(#1)}} {
+ \ctxlua{moduledata.asciimath.show.dirty(\recurselevel,true)}
+ \blank[medium,samepage]
+ }
+ }
+ \ctxlua{moduledata.asciimath.show.result(#1)}
+ \blank
+ \endgroup}
+
+\unexpanded\def\ShowAsciiMathStart
+ {\begingroup
+ \let\asciimathoptext\asciimathoptexttraced
+ \setuptyping[\v!buffer][\c!before=,\c!after=]
+ \setupmargindata[\v!left][\c!style=]}
+
+\unexpanded\def\ShowAsciiMathStop
+ {\endgroup}
+
+\unexpanded\def\ShowAsciiMath
+ {\dodoubleempty\doShowAsciiMath}
+
+\unexpanded\def\doShowAsciiMath[#1][#2]%
+ {\iffirstargument
+ \ShowAsciiMathStart
+ \ShowAsciiMathLoad[#1]
+ \ifsecondargument
+ \ShowAsciiMathIgnore[#2]
+ \fi
+ \dorecurse{\ShowAsciiMathMax}{\ShowAsciiMathResult\recurselevel}
+ \page
+ \ShowAsciiMathStats
+ \ShowAsciiMathStop
+ \fi}
+
+\unexpanded\def\xmlShowAsciiMath#1#2%
+ {\iffirstargument
+ \ShowAsciiMathStart
+ \ShowAsciiMathXML{#1}{#2}%
+ \dorecurse{\ShowAsciiMathMax}{\ShowAsciiMathResult\recurselevel}
+ \page
+ \ShowAsciiMathStats
+ \ShowAsciiMathStop
+ \fi}
+
+\unexpanded\def\ShowAsciiMathSave
+ {\dosingleempty\doShowAsciiMathSave}
+
+\unexpanded\def\doShowAsciiMathSave[#1]%
+ {\ctxlua{moduledata.asciimath.show.save("#1")}}
+
+\protect
+
+\startsetups asciimath:layout
+
+ \setupbodyfont
+ % [pagella,10pt]
+ [dejavu,10pt]
+
+ \setuplayout
+ [backspace=35mm,
+ leftmargin=20mm,
+ rightmargindistance=0pt,
+ leftmargindistance=5mm,
+ cutspace=1cm,
+ topspace=1cm,
+ bottomspace=1cm,
+ width=middle,
+ height=middle,
+ header=0cm,
+ footer=1cm]
+
+ \setupheadertexts
+ []
+
+ \setupfootertexts
+ [\currentdate][\pagenumber]
+
+ \setupalign
+ [flushleft,verytolerant,stretch]
+
+ \dontcomplain
+
+\stopsetups
+
+\stopmodule
+
+\continueifinputfile{x-asciimath.mkiv}
+
+%D This will become an extra.
+
+\showframe
+
+\setups[asciimath:layout]
+
+% \enabletrackers[modules.asciimath.mapping]
+% \enabletrackers[modules.asciimath.detail]
+
+% \starttext
+% \enablemode[asciimath:show:dirty]
+% \ShowAsciiMath[e:/temporary/asciimath/*.xml]
+% % \ShowAsciiMathSave[e:/temporary/asciimath/asciimath.lua]
+% \stoptext
+
+\starttext
+\unexpanded\def\MyAsciiMath#1{\startformula\asciimath{#1}\stopformula}
+\startlines
+\MyAsciiMath{x^2 / 10 // z_12^34 / 20}
+% \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}}
+% \MyAsciiMath{x^2+y_1+z_12^34}
+% \MyAsciiMath{sin^-1(x)}
+% \MyAsciiMath{d/dx f(x)=lim_(h->0) (f(x+h)-f(x))/h}
+% \MyAsciiMath{f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n}
+% \MyAsciiMath{int_0^1 f(x)dx}
+% \MyAsciiMath{int^1_0 f(x)dx}
+% \MyAsciiMath{a//b}
+% \MyAsciiMath{a//\alpha}
+% \MyAsciiMath{(a/b)/(d/c)}
+% \MyAsciiMath{((a*b))/(d/c)}
+% \MyAsciiMath{[[a,b],[c,d]]((n),(k))}
+% \MyAsciiMath{1/x={(1,text{if } x!=0),(text{undefined},if x=0):}}
+% \MyAsciiMath{{ (1,2), (x,(x + text(x))) }}
+% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,text(x))}}
+% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,x text(x))}}
+% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,x text(xyz))}}
+% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,text(xyz)+1+text(hans))}}
+% \MyAsciiMath{<<a,b>> text{and} {:(x,y),(u,v):}}
+% \MyAsciiMath{(a,b] = {x text(in) RR | a < x <= b}}
+% \MyAsciiMath{a/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c)}
+% \MyAsciiMath{ (a/b) // (c/d) = ( (a * d) / (b * d) ) // ( (b * c) / (b * d) ) = (a * d) / (b * c)}
+% \MyAsciiMath{sin(x+1)_3^2/b / c/d}
+% \MyAsciiMath{{:{:sin(x+1)_3^2:}/b:} / {:c/d:}}
+% \MyAsciiMath{cos(a) + sin(x+1)_3^2/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c)}
+% \MyAsciiMath{S_(11)}
+% \MyAsciiMath{f(x)}
+% \MyAsciiMath{sin(x)}
+% \MyAsciiMath{sin(x+1)}
+% \MyAsciiMath{sin^-1(x)}
+% \MyAsciiMath{sin(2x)}
+% \MyAsciiMath{a_2^2}
+% \MyAsciiMath{( (S_(11),S_(12),S_(1n)),(vdots,ddots,vdots),(S_(m1),S_(m2),S_(mn)) ]}
+% \MyAsciiMath{frac a b}
+% \MyAsciiMath{sin(x)/2 // cos(x)/pi}
+% \MyAsciiMath{a/13 // c/d}
+% \MyAsciiMath{a/b // c/d}
+% \MyAsciiMath{x}
+% \MyAsciiMath{x^2}
+% \MyAsciiMath{sqrt x}
+% \MyAsciiMath{sqrt (x)}
+% \MyAsciiMath{root 2 x}
+% \MyAsciiMath{x+x}
+% \MyAsciiMath{x/3}
+% \MyAsciiMath{x^2 / 10}
+% \MyAsciiMath{x^2 / 10 // z_12^34 / 20}
+% \MyAsciiMath{a^23}
+% \MyAsciiMath{a^{:b^23:}+3x}
+% \MyAsciiMath{a/b / c/d}
+% \MyAsciiMath{sin(x)/b / c/d}
+% \MyAsciiMath{sin(x)/b // c/d}
+% \MyAsciiMath{a/b / c/d = (a * d) / (b * d) / (b * c) / (b * d) = (a * d) / (b * c) }
+% \MyAsciiMath{{:{:x^2:} / 10:} // {:{:z_12^34 :} / 20:}}
+% \MyAsciiMath{x^2+y_1+z_12^34}
+% \MyAsciiMath{sin^-1(x)}
+% \MyAsciiMath{d/dx f(x)=lim_(h->0) (f(x+h)-f(x))/h}
+% \MyAsciiMath{f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n}
+% \MyAsciiMath{int_0^1 f(x)dx}
+% \MyAsciiMath{int^1_0 f(x)dx}
+% \MyAsciiMath{2x}
+% \MyAsciiMath{a//b}
+% \MyAsciiMath{a//\alpha}
+% \MyAsciiMath{(a/b)/(d/c)}
+% \MyAsciiMath{((a*b))/(d/c)}
+% \MyAsciiMath{[[a,b],[c,d]]((n),(k))}
+% \MyAsciiMath{1/x={(1,text{if } x!=0),(text{undefined},if x=0):}}
+% \MyAsciiMath{{ (1,2), (x,(x + text(x))) }}
+% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,text(x))}}
+% \MyAsciiMath{{(1,2),(x,(x+text(x))),(x,x text(x))}}
+% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,x text(xyz))}}
+% \MyAsciiMath{{(1,2/2),(x,(x+x^22+sqrt(xx))),(x,text(xyz)+1+text(hans))}}
+% \MyAsciiMath{<<a,b>> text{and} {:(x,y),(u,v):}}
+% \MyAsciiMath{(a,b] = {x text(in) RR | a < x <= b}}
+% \MyAsciiMath{x^-2}
+% \MyAsciiMath{x^2(x-1/16)=0}
+% \MyAsciiMath{y= ((1/4)) ^x}
+% \MyAsciiMath{log (0,002) / (log(1/4))}
+% \MyAsciiMath{x=ax+b \ oeps}
+% \MyAsciiMath{x=\ ^ (1/4) log(x)}
+% \MyAsciiMath{x=\ ^ (1/4) log(0 ,002 )= log(0,002) / (log(1/4))}
+% \MyAsciiMath{x^ (-1 1/2) =1/x^ (1 1/2)=1/ (x^1*x^ (1/2)) =1/ (xsqrt(x))}
+% \MyAsciiMath{x^2(10 -x)&gt;2 x^2}
+% \MyAsciiMath{x^4&gt;x}
+\stoplines
+
+\setupasciimath[splitmethod=3,symbol={{,}}]
+
+\startlines
+\asciimath{sqrt 1}
+\asciimath{sqrt 1.2}
+\asciimath{sqrt 1.2}
+\asciimath{1}
+\asciimath{12}
+\asciimath{123}
+\asciimath{1234}
+\asciimath{12345}
+\asciimath{123456}
+\asciimath{1234567}
+\asciimath{12345678}
+\asciimath{123456789}
+\asciimath{1.1}
+\asciimath{12.12}
+\asciimath{1234.123}
+\asciimath{1234.1234}
+\asciimath{12345.1234}
+\asciimath{1234.12345}
+\asciimath{12345.12345}
+\asciimath{123456.123456}
+\asciimath{1234567.1234567}
+\asciimath{12345678.12345678}
+\asciimath{123456789.123456789}
+\asciimath{0.1234}
+\asciimath{1234.0}
+\asciimath{1234.00}
+\asciimath{0.123456789}
+\stoplines
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-calcmath.lua b/tex/context/modules/mkiv/x-calcmath.lua
new file mode 100644
index 000000000..c96d8d0ac
--- /dev/null
+++ b/tex/context/modules/mkiv/x-calcmath.lua
@@ -0,0 +1,363 @@
+if not modules then modules = { } end modules ['x-calcmath'] = {
+ version = 1.001,
+ comment = "companion to x-calcmath.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- this really needs to be redone
+
+local format, lower, upper, gsub, sub = string.format, string.lower, string.upper, string.gsub, string.sub
+local concat = table.concat
+local lpegmatch = lpeg.match
+
+local calcmath = { }
+local moduledata = moduledata or { }
+moduledata.calcmath = calcmath
+
+local context = context
+
+local list_1 = {
+ "median", "min", "max", "round", "ln", "log",
+ "sin", "cos", "tan", "sinh", "cosh", "tanh"
+}
+local list_2 = {
+ "int", "sum", "prod"
+}
+local list_3 = {
+ "f", "g"
+}
+local list_4 = {
+ "pi", "inf"
+}
+
+local list_1_1 = { }
+local list_2_1 = { }
+local list_2_2 = { }
+local list_2_3 = { }
+local list_4_1 = { }
+
+local frozen = false
+
+local function freeze()
+ for k=1,#list_1 do
+ local v = list_1[k]
+ list_1_1[v] = "\\".. upper(v) .." "
+ end
+ for k=1,#list_2 do
+ local v = list_2[k]
+ list_2_1[v .. "%((.-),(.-),(.-)%)"] = "\\" .. upper(v) .. "^{%1}_{%2}{%3}"
+ list_2_2[v .. "%((.-),(.-)%)"] = "\\" .. upper(v) .. "^{%1}{%2}"
+ list_2_3[v .. "%((.-)%)"] = "\\" .. upper(v) .. "{%1}"
+ end
+ for k=1,#list_4 do
+ local v = list_4[k]
+ list_4_1[v] = "\\" .. upper(v)
+ end
+ frozen = true
+end
+
+local entities = {
+ ['gt'] = '>',
+ ['lt'] = '<',
+}
+
+local symbols = {
+ ["<="] = "\\LE ",
+ [">="] = "\\GE ",
+ ["=<"] = "\\LE ",
+ ["=>"] = "\\GE ",
+ ["=="] = "\\EQ ",
+ ["<" ] = "\\LT ",
+ [">" ] = "\\GT ",
+ ["="] = "\\EQ ",
+}
+
+local function nsub(str,tag,pre,post)
+ return (gsub(str,tag .. "(%b())", function(body)
+ return pre .. nsub(sub(body,2,-2),tag,pre,post) .. post
+ end))
+end
+
+local function totex(str,mode)
+ if not frozen then freeze() end
+ local n = 0
+ -- crap
+ str = gsub(str,"%s+",' ')
+ -- xml
+ str = gsub(str,"&(.-);",entities)
+ -- ...E...
+ str = gsub(str,"([%-%+]?[%d%.%+%-]+)E([%-%+]?[%d%.]+)", "{\\SCINOT{%1}{%2}}")
+ -- ^-..
+ str = gsub(str,"%^([%-%+]*%d+)", "^{%1}")
+ -- ^(...)
+ str = nsub(str,"%^", "^{", "}")
+ -- 1/x^2
+ repeat
+ str, n = gsub(str,"([%d%w%.]+)/([%d%w%.]+%^{[%d%w%.]+})", "\\frac{%1}{%2}")
+ until n == 0
+ -- todo: autoparenthesis
+ -- int(a,b,c)
+ for k, v in next, list_2_1 do
+ repeat str, n = gsub(str,k,v) until n == 0
+ end
+ -- int(a,b)
+ for k, v in next, list_2_2 do
+ repeat str, n = gsub(str,k,v) until n == 0
+ end
+ -- int(a)
+ for k, v in next, list_2_3 do
+ repeat str, n = gsub(str,k,v) until n == 0
+ end
+ -- sin(x) => {\\sin(x)}
+ for k, v in next, list_1_1 do
+ repeat str, n = gsub(str,k,v) until n == 0
+ end
+ -- mean
+ str = nsub(str, "mean", "\\OVERLINE{", "}")
+ -- (1+x)/(1+x) => \\FRAC{1+x}{1+x}
+ repeat
+ str, n = gsub(str,"(%b())/(%b())", function(a,b)
+ return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. sub(b,2,-2) .. "}"
+ end )
+ until n == 0
+ -- (1+x)/x => \\FRAC{1+x}{x}
+ repeat
+ str, n = gsub(str,"(%b())/([%+%-]?[%.%d%w]+)", function(a,b)
+ return "\\FRAC{" .. sub(a,2,-2) .. "}{" .. b .. "}"
+ end )
+ until n == 0
+ -- 1/(1+x) => \\FRAC{1}{1+x}
+ repeat
+ str, n = gsub(str,"([%.%d%w]+)/(%b())", function(a,b)
+ return "\\FRAC{" .. a .. "}{" .. sub(b,2,-2) .. "}"
+ end )
+ until n == 0
+ -- 1/x => \\FRAC{1}{x}
+ repeat
+ str, n = gsub(str,"([%.%d%w]+)/([%+%-]?[%.%d%w]+)", "\\FRAC{%1}{%2}")
+ until n == 0
+ -- times
+ str = gsub(str,"%*", " ")
+ -- symbols -- we can use a table substitution here
+ str = gsub(str,"([<>=][<>=]*)", symbols)
+ -- functions
+ str = nsub(str,"sqrt", "\\SQRT{", "}")
+ str = nsub(str,"exp", "e^{", "}")
+ str = nsub(str,"abs", "\\left|", "\\right|")
+ -- d/D
+ str = nsub(str,"D", "{\\FRAC{\\MBOX{d}}{\\MBOX{d}x}{(", ")}}")
+ str = gsub(str,"D([xy])", "\\FRAC{{\\RM d}%1}{{\\RM d}x}")
+ -- f/g
+ for k,v in next, list_3 do -- todo : prepare k,v
+ str = nsub(str,"D"..v,"{\\RM "..v.."}^{\\PRIME}(",")")
+ str = nsub(str,v,"{\\RM "..v.."}(",")")
+ end
+ -- more symbols
+ for k,v in next, list_4_1 do
+ str = gsub(str,k,v)
+ end
+ -- parenthesis (optional)
+ if mode == 2 then
+ str = gsub(str,"%(", "\\left(")
+ str = gsub(str,"%)", "\\right)")
+ end
+ -- csnames
+ str = gsub(str,"(\\[A-Z]+)", lower)
+ -- report
+ return str
+end
+
+calcmath.totex = totex
+
+function calcmath.tex(str,mode)
+ context(totex(str))
+end
+
+function calcmath.xml(id,mode)
+ context(totex(lxml.id(id).dt[1],mode))
+end
+
+-- work in progress ... lpeg variant
+
+if false then
+
+ -- todo:
+
+ -- maybe rewrite to current lpeg, i.e. string replacement and no Cc's
+
+ -- table approach we have now is less efficient but more flexible
+
+ -- D \frac {\rm d} {{\rm d}x}
+ -- Dx Dy \frac {{\rm d}y} {{\rm d}x}
+ -- Df Dg {\rm f}^{\prime}
+ -- f() g() {\rm f}()
+
+ -- valid utf8
+
+ local S, P, R, C, V, Cc, Ct = lpeg.S, lpeg.P, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, lpeg.Ct
+
+ local space = S(" \n\r\t")^0
+ local integer = P("-")^-1 * R("09")^1
+ local realpart = P("-")^-1 * R("09")^1 * S(".")^1 * R("09")^1
+ local number = Cc("number") * C(integer) * space
+ local real = Cc("real") * C(realpart) * space
+ local float = Cc("float") * C(realpart) * lpeg.P("E") * lpeg.C(integer) * space
+ local identifier = Cc("identifier") * C(R("az","AZ")) * space
+ local compareop = Cc("compare") * C(P("<") + P("=") + P(">") + P(">=") + P("<=") + P("&gt;") + P("&lt;")) * space
+ local factorop = Cc("factor") * C(S("+-^_,")) * space
+ local termop = Cc("term") * C(S("*/")) * space
+ local constant = Cc("constant") * C(P("pi") + lpeg.P("inf")) * space
+ local functionop = Cc("function") * C(R("az")^1) * space
+ local open = P("(") * space
+ local close = P(")") * space
+
+ local grammar = P {
+ "expression",
+ expression = Ct(V("factor") * ((factorop+compareop) * V("factor"))^0),
+ factor = Ct(V("term") * (termop * V("term"))^0),
+ term = Ct(
+ float + real + number +
+ (open * V("expression") * close) +
+ (functionop * open * (V("expression") * (P(",") * V("expression"))^0) * close) +
+ (functionop * V("term")) +
+ constant + identifier
+ ),
+ }
+
+ local parser = space * grammar * -1
+
+ local function has_factor(t)
+ for i=1,#t do
+ if t[i] == "factor" then
+ return true
+ end
+ end
+ end
+
+ -- can be sped up if needed ...
+
+ function totex(t)
+ if t then
+ local one = t[1]
+ if type(one) == "string" then
+ local two, three = t[2], t[3]
+ if one == "number" then
+ context(two)
+ elseif one == "real" then
+ context(two)
+ elseif one == "float" then
+ context("\\scinot{",two,"}{",three,"}")
+ elseif one == "identifier" then
+ context(two)
+ elseif one == "constant" then
+ context("\\"..two)
+ elseif one == "function" then
+ if two == "sqrt" then
+ context("\\sqrt{")
+ totex(three)
+ context("}")
+ elseif two == "exp" then
+ context(" e^{")
+ totex(three)
+ context("}")
+ elseif two == "abs" then
+ context("\\left|")
+ totex(three)
+ context("\\right|")
+ elseif two == "mean" then
+ context("\\overline{")
+ totex(three)
+ context("}")
+ elseif two == "int" or two == "prod" or two == "sum" then
+ local four, five = t[4], t[5]
+ if five then
+ context("\\"..two.."^{") -- context[two]("{")
+ totex(three)
+ context("}_{")
+ totex(four)
+ context("}")
+ totex(five)
+ elseif four then
+ context("\\"..two.."^{")
+ totex(three)
+ context("}")
+ totex(four)
+ elseif three then
+ context("\\"..two.." ") -- " " not needed
+ totex(three)
+ else
+ context("\\"..two)
+ end
+ else
+ context("\\"..two.."(")
+ totex(three)
+ context(")")
+ end
+ end
+ else
+ local nt = #t
+ local hasfactor = has_factor(t)
+ if hasfactor then
+ context("\\left(")
+ end
+ totex(one)
+ for i=2,nt,3 do
+ local what, how, rest = t[i], t[i+1], t[i+2]
+ if what == "factor" then
+ if how == '^' or how == "_" then
+ context(how)
+ context("{")
+ totex(rest)
+ context("}")
+ else
+ context(how)
+ totex(rest)
+ end
+ elseif what == "term" then
+ if how == '/' then
+ context("\\frac{")
+ totex(rest)
+ context("}{")
+ totex(t[i+3] or "")
+ context("}")
+ elseif how == '*' then
+ context("\\times")
+ totex(rest)
+ else
+ context(how)
+ totex(three)
+ end
+ elseif what == "compare" then
+ if two == ">=" then
+ context("\\ge")
+ elseif two == "<=" then
+ context("\\le")
+ elseif two == "&gt;" then
+ context(">")
+ elseif two == "&lt;" then
+ context("<")
+ end
+ totex(three)
+ end
+ end
+ if hasfactor then
+ context("\\right)")
+ end
+ end
+ end
+ end
+
+ calcmath = { }
+
+ function calcmath.parse(str)
+ return lpegmatch(parser,str)
+ end
+
+ function calcmath.tex(str)
+ str = totex(lpegmatch(parser,str))
+ return (str == "" and "[error]") or str
+ end
+
+end
diff --git a/tex/context/modules/mkiv/x-calcmath.mkiv b/tex/context/modules/mkiv/x-calcmath.mkiv
new file mode 100644
index 000000000..dda88bb3e
--- /dev/null
+++ b/tex/context/modules/mkiv/x-calcmath.mkiv
@@ -0,0 +1,80 @@
+%D \module
+%D [ file=m-calcmath,
+%D version=2006.04.24, % 1999.11.06,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Calculator Math,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Lua code.
+
+\registerctxluafile{x-calcmath}{}
+
+\def\ctxmodulecalcmath#1{\ctxlua{moduledata.calcmath.#1}}
+
+%D Interface:
+
+\unprotect
+
+\unexpanded\def\inlinecalcmath #1{\mathematics{\ctxmodulecalcmath{tex("#1",1)}}}
+\unexpanded\def\displaycalcmath#1{\startformula\ctxmodulecalcmath{tex("#1",2)}\stopformula}
+
+\let\calcmath\inlinecalcmath
+
+\let\icm\inlinecalcmath
+\let\dcm\displaycalcmath
+
+\startxmlsetups xml:cam:define
+ \xmlsetsetup {\xmldocument} {cam:*} {*}
+ \xmlsetsetup {\xmldocument} {(icm|dcm)} {cam:*}
+\stopxmlsetups
+
+\xmlregisterns{cam}{calcmath}
+
+\xmlregistersetup{xml:cam:define}
+
+% tex -> lua -> tex -> lua -> tex
+% \mathematics{\ctxmodulecalcmath{xml(\!!bs\xmlflush{#1}\!!es,1)}}
+% tex -> lua -> tex
+% \mathematics{\ctxmodulecalcmath{xml("#1",1)}}%
+
+\startxmlsetups cam:i
+ \mathematics{\ctxmodulecalcmath{xml("#1",1)}}%
+\stopxmlsetups
+
+\startxmlsetups cam:d
+ \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula
+\stopxmlsetups
+
+\startxmlsetups cam:icm
+ \mathematics{\ctxmodulecalcmath{xml("#1",1)}}
+\stopxmlsetups
+
+\startxmlsetups cam:dcm
+ \startformula\ctxmodulecalcmath{xml("#1",2)}\stopformula
+\stopxmlsetups
+
+\protect \endinput
+
+\starttext
+
+% \calcmath{sin(x) + x^2 + x^(1+x) + 1/x^2 + mean(x+mean(y))}
+% \calcmath{int(a,b,c)}
+% \calcmath{(1+x)/(1+x) + (1+x)/(1+(1+x)/(1+x))}
+% \calcmath{10E-2}
+% \calcmath{(1+x)/x}
+% \calcmath{(1+x)/12}
+% \calcmath{(1+x)/-12}
+% \calcmath{1/-12}
+% \calcmath{12x/(1+x)}
+% \calcmath{exp(x+exp(x+1))}
+% \calcmath{abs(x+abs(x+1)) + pi + inf}
+% \calcmath{Dx Dy}
+% \calcmath{D(x+D(y))}
+% \calcmath{Df(x)}
+% \calcmath{g(x)}
diff --git a/tex/context/modules/mkiv/x-cals.lua b/tex/context/modules/mkiv/x-cals.lua
new file mode 100644
index 000000000..3af6106d8
--- /dev/null
+++ b/tex/context/modules/mkiv/x-cals.lua
@@ -0,0 +1,221 @@
+if not modules then modules = { } end modules ['x-cals'] = {
+ version = 1.001,
+ comment = "companion to x-cals.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local next = next
+local format, lower = string.format, string.lower
+local xmlsprint, xmlcprint, xmlcollected, xmlelements = xml.sprint, xml.cprint, xml.collected, xml.elements
+local n_todimen, s_todimen = number.todimen, string.todimen
+
+-- there is room for speedups as well as cleanup (using context functions)
+
+local cals = { }
+moduledata.cals = cals
+lxml.mathml = cals -- for the moment
+
+cals.ignore_widths = false
+cals.shrink_widths = false
+cals.stretch_widths = false
+
+-- the following flags only apply to columns that have a specified width
+--
+-- proportional : shrink or stretch proportionally to the width
+-- equal : shrink or stretch equaly distributed
+-- n < 1 : shrink or stretch proportionally to the width but multiplied by n
+--
+-- more clever things, e.g. the same but applied to unspecified widths
+-- has to happen at the core-ntb level (todo)
+
+local halignments = {
+ left = "flushleft",
+ right = "flushright",
+ center = "middle",
+ centre = "middle",
+ justify = "normal",
+}
+
+local valignments = {
+ top = "high",
+ bottom = "low",
+ middle = "lohi",
+}
+
+local function adapt(widths,b,w,delta,sum,n,what)
+ if b == "equal" then
+ delta = delta/n
+ for k, v in next, w do
+ widths[k] = n_todimen(v - delta)
+ end
+ elseif b == "proportional" then
+ delta = delta/sum
+ for k, v in next, w do
+ widths[k] = n_todimen(v - v*delta)
+ end
+ elseif type(b) == "number" and b < 1 then
+ delta = b*delta/sum
+ for k, v in next, w do
+ widths[k] = n_todimen(v - v*delta)
+ end
+ end
+end
+
+local function getspecs(root, pattern, names, widths)
+ -- here, but actually we need this in core-ntb.tex
+ -- but ideally we need an mkiv enhanced core-ntb.tex
+ local ignore_widths = cals.ignore_widths
+-- local shrink_widths = at.option == "shrink" or cals.shrink_widths
+-- local stretch_widths = at.option == "stretch" or cals.stretch_widths
+ local shrink_widths = cals.shrink_widths
+ local stretch_widths = cals.stretch_widths
+ for e in xmlcollected(root,pattern) do
+ local at = e.at
+ local column = at.colnum
+ if column then
+ if not ignore_widths then
+ local width = at.colwidth
+ if width then
+ widths[tonumber(column)] = lower(width)
+ end
+ end
+ local name = at.colname
+ if name then
+ names[name] = tonumber(column)
+ end
+ end
+ end
+ if ignore_width then
+ -- forget about it
+ elseif shrink_widths or stretch_widths then
+ local sum, n, w = 0, 0, { }
+ for _, v in next, widths do
+ n = n + 1
+ v = (type(v) == "string" and s_todimen(v)) or v
+ if v then
+ w[n] = v
+ sum = sum + v
+ end
+ end
+ local hsize = tex.hsize
+ if type(hsize) == "string" then
+ hsize = s_todimen(hsize)
+ end
+ local delta = sum - hsize
+ if shrink_widths and delta > 0 then
+ adapt(widths,shrink_widths,w,delta,sum,n,"shrink")
+ elseif stretch_widths and delta < 0 then
+ adapt(widths,stretch_widths,w,delta,sum,n,"stretch")
+ end
+ end
+end
+
+local function getspans(root, pattern, names, spans)
+ for e in xmlcollected(root,pattern) do
+ local at = e.at
+ local name, namest, nameend = at.colname, names[at.namest or "?"], names[at.nameend or "?"]
+ if name and namest and nameend then
+ spans[name] = tonumber(nameend) - tonumber(namest) + 1
+ end
+ end
+end
+
+local bTR, eTR, bTD, eTD = context.bTR, context.eTR, context.bTD, context.eTD
+
+function cals.table(root,namespace)
+
+ local prefix = (namespace or "cals") .. ":"
+
+ local prefix = namespace and namespace ~= "" and (namespace .. ":") or ""
+ local p = "/" .. prefix
+
+ local tgroupspec = p .. "tgroup"
+ local colspec = p .. "colspec"
+ local spanspec = p .. "spanspec"
+ local hcolspec = p .. "thead" .. p .. "colspec"
+ local bcolspec = p .. "tbody" .. p .. "colspec"
+ local fcolspec = p .. "tfoot" .. p .. "colspec"
+ local entryspec = p .. "entry" .. "|" .. prefix .. "entrytbl" -- shouldn't that be p ?
+ local hrowspec = p .. "thead" .. p .. "row"
+ local browspec = p .. "tbody" .. p .. "row"
+ local frowspec = p .. "tfoot" .. p .. "row"
+
+ local function tablepart(root, xcolspec, xrowspec, before, after) -- move this one outside
+ before()
+ local at = root.at
+ local pphalign, ppvalign = at.align, at.valign
+ local names, widths, spans = { }, { }, { }
+ getspecs(root, colspec , names, widths)
+ getspecs(root, xcolspec, names, widths)
+ getspans(root, spanspec, names, spans)
+ for r, d, k in xmlelements(root,xrowspec) do
+ bTR()
+ local dk = d[k]
+ local at = dk.at
+ local phalign, pvalign = at.align or pphalign, at.valign or ppvalign -- todo: __p__ test
+ local col = 1
+ for rr, dd, kk in xmlelements(dk,entryspec) do
+ local dk = dd[kk]
+ if dk.tg == "entrytbl" then
+ -- bTD(function() cals.table(dk) end)
+ bTD()
+ context("{")
+ cals.table(dk)
+ context("}")
+ eTD()
+ col = col + 1
+ else
+ local at = dk.at
+ local b, e, s, m = names[at.namest or "?"], names[at.nameend or "?"], spans[at.spanname or "?"], at.morerows
+ local halign, valign = at.align or phalign, at.valign or pvalign
+ if b and e then
+ s = e - b + 1
+ end
+ if halign then
+ halign = halignments[halign]
+ end
+ if valign then
+ valign = valignments[valign]
+ end
+ local width = widths[col]
+ if s or m or halign or valign or width then -- currently only english interface !
+ bTD {
+ nx = s or 1,
+ ny = (m or 0) + 1,
+ align = format("{%s,%s}",halign or "flushleft",valign or "high"),
+ width = width or "fit",
+ }
+ else
+ bTD {
+ align = "{flushleft,high}",
+ width = "fit", -- else problems with vertical material
+ }
+ end
+ xmlcprint(dk)
+ eTD()
+ col = col + (s or 1)
+ end
+ end
+ eTR()
+ end
+ after()
+ end
+
+ for tgroup in lxml.collected(root,tgroupspec) do
+ context.directsetup("cals:table:before")
+ lxml.directives.before(root,"cdx") -- "cals:table"
+ context.bgroup()
+ lxml.directives.setup(root,"cdx") -- "cals:table"
+ context.bTABLE()
+ tablepart(tgroup, hcolspec, hrowspec, context.bTABLEhead, context.eTABLEhead)
+ tablepart(tgroup, bcolspec, browspec, context.bTABLEbody, context.eTABLEbody)
+ tablepart(tgroup, fcolspec, frowspec, context.bTABLEfoot, context.eTABLEfoot)
+ context.eTABLE()
+ context.egroup()
+ lxml.directives.after(root,"cdx") -- "cals:table"
+ context.directsetup("cals:table:after")
+ end
+
+end
diff --git a/tex/context/modules/mkiv/x-cals.mkiv b/tex/context/modules/mkiv/x-cals.mkiv
new file mode 100644
index 000000000..31ba2d213
--- /dev/null
+++ b/tex/context/modules/mkiv/x-cals.mkiv
@@ -0,0 +1,45 @@
+%D \module
+%D [ file=x-cals,
+%D version=2007.09.05,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Cals table renderer,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt XML Macros / Cals Tables}
+
+\startmodule [cals]
+
+\registerctxluafile{x-cals}{}
+
+% \startxmlsetups xml:cals:process
+% \xmlsetsetup {#1} {cals:table} {*}
+% \stopxmlsetups
+% \startxmlsetups cals:table
+% \ctxlua{moduledata.cals.table("#1")}
+% \stopxmlsetups
+% \xmlregistersetup{xml:cals:process}
+
+\startxmlsetups xml:cals:process
+% \xmlsetfunction {\xmldocument} {cals:table} {moduledata.cals.table}
+ \xmlsetfunction {#1} {cals:table} {moduledata.cals.table}
+\stopxmlsetups
+
+\startxmlsetups xml:cals:nonamespace
+% \xmlsetfunction {\xmldocument} {table} {moduledata.cals.table}
+ \xmlsetfunction {#1} {table} {moduledata.cals.table}
+\stopxmlsetups
+
+\xmlregistersetup{xml:cals:process}
+
+\xmlregisterns{cals}{cals}
+
+%D One can register the nonamespace variant for cases where the cals
+%D model is embedded in the parent DTD.
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/x-chemml.lua b/tex/context/modules/mkiv/x-chemml.lua
new file mode 100644
index 000000000..79c1d9525
--- /dev/null
+++ b/tex/context/modules/mkiv/x-chemml.lua
@@ -0,0 +1,51 @@
+if not modules then modules = { } end modules ['x-chemml'] = {
+ version = 1.001,
+ comment = "companion to x-chemml.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- not yet acceptable cld
+
+local format, lower, upper, gsub, sub, match = string.format, string.lower, string.upper, string.gsub, string.sub, string.match
+local concat = table.concat
+
+local chemml = { }
+local moduledata = moduledata or { }
+moduledata.chemml = chemml
+
+function chemml.pi(id)
+ local str = xml.content(lxml.id(id))
+ local _, class, key, value = match(str,"^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*$")
+ if key and value then
+ context("\\setupCMLappearance[%s][%s=%s]",class, key, value)
+ end
+end
+
+function chemml.do_graphic(id)
+ local t = { }
+ for r, d, k in xml.elements(lxml.id(id),"cml:graphic") do
+ t[#t+1] = xml.tostring(d[k].dt)
+ end
+ context(concat(t,","))
+end
+
+function chemml.no_graphic(id)
+ local t = { }
+ for r, d, k in xml.elements(lxml.id(id),"cml:text|cml:oxidation|cml:annotation") do
+ local dk = d[k]
+ if dk.tg == "oxidation" then
+ t[#t+1] = format("\\chemicaloxidation{%s}{%s}{%s}",r.at.sign or "",r.at.n or 1,xml.tostring(dk.dt))
+ elseif dk.tg == "annotation" then
+ local location = r.at.location or "r"
+ local caption = xml.content(xml.first(dk,"cml:caption"))
+ local text = xml.content(xml.first(dk,"cml:text"))
+ t[#t+1] = format("\\doCMLannotation{%s}{%s}{%s}",location,caption,text)
+ else
+ t[#t+1] = xml.tostring(dk.dt) or ""
+ end
+ end
+ context(concat(t,","))
+end
+
diff --git a/tex/context/modules/mkiv/x-chemml.mkiv b/tex/context/modules/mkiv/x-chemml.mkiv
new file mode 100644
index 000000000..bb9065921
--- /dev/null
+++ b/tex/context/modules/mkiv/x-chemml.mkiv
@@ -0,0 +1,228 @@
+%D \module
+%D [ file=x-cml,
+%D version=2007.09.03, % reimplementation
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=MkIV ChemML renderer,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% This needs an update!
+
+\writestatus{loading}{ConTeXt XML Macros / Chemistry}
+
+\registerctxluafile{x-chemml}{}
+
+\def\ctxmodulechemml#1{\ctxlua{moduledata.chemml.#1}}
+
+%D The following code assumes a load||flush approach to \XML.
+
+\unprotect
+
+\startxmlsetups xml:cml:process
+ \xmlstrip {#1} {cml:chem|cml:ichem|cml:dchem|cml:reaction|cml:molecule|cml:ion|cml:structure}
+
+ \xmlgrab {#1} {cml:*} {cml:*}
+ \xmlgrab {#1} {cml:gives|cml:equilibrium|cml:mesomeric} {cml:arrow}
+ \xmlgrab {#1} {cml:plus|cml:minus|cml:equal} {cml:operator}
+ \xmlgrab {#1} {cml:bond|cml:singlebond|cml:doublebound|cml:triplebond} {cml:bond}
+
+ \xmlgrab {#1} {pi::chemml} {cml:pi}
+\stopxmlsetups
+
+\xmlregistersetup{xml:cml:process}
+
+\xmlregisterns{cml}{chemml}
+
+\unexpanded\def\setupCMLappearance[#1]{\dodoubleargument\getparameters[@@CML#1]} % old stuff
+
+\setupCMLappearance [ion] [\c!alternative=\v!a]
+
+\def\doifelseCMLvariable#1#2#3% id key value
+ {\doifelse{\xmlatt{#1}{#2}}{#3}
+ \firstoftwoarguments
+ {\doifelse{\getvalue{@@CML\xmltag{#1}#2}}{#3}
+ \firstoftwoarguments
+ \secondoftwoarguments}}
+
+\startxmlsetups cml:pi
+ \ctxmodulechemml{pi(#1)}
+\stopxmlsetups
+
+\startxmlsetups cml:chem
+ \automathematics{\xmlflush{#1}}
+\stopxmlsetups
+\startxmlsetups cml:ichem
+ \inlinemathematics{\xmlflush{#1}}
+\stopxmlsetups
+\startxmlsetups cml:dchem
+ \displaymathematics{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups cml:reaction
+ \xmlflush{#1}
+\stopxmlsetups
+
+\unexpanded\def\doCMLtext#1#2#3% main top bot
+ {\setbox0\hbox{\doifsomething{#2}{\txx\setstrut\strut\ignorespaces#2\unskip}}%
+ \setbox2\hbox{\ignorespaces\strut#1\unskip}%
+ \setbox4\hbox{\doifsomething{#3}{\txx\setstrut\strut\ignorespaces#3\unskip}}%
+ \scratchdimen=\wd2\advance\scratchdimen-.5em
+ \ifdim\wd0>\scratchdimen
+ \setbox0\hbox spread .5em{\hss\box0\hss}%
+ \fi
+ \ifdim\wd4>\scratchdimen
+ \setbox4\hbox spread .5em{\hss\box4\hss}%
+ \fi
+ \setbox6=\vbox
+ {\offinterlineskip\halign{\hss##\hss\cr\copy0\cr\copy2\cr\copy4\cr}}%
+ \hbox{\lower\ht4\hbox{\lower\dp2\box6}}}
+
+\def\doCMLamount#1%
+ {\scratchcounter0\xmlatt{#1}{n}\relax
+ \ifnum\scratchcounter>0 \number\scratchcounter \fi}
+
+\startxmlsetups cml:molecule
+ \doCMLtext
+ {\doCMLamount{#1}
+ \xmlall{#1}{cml:atom|cml:bond|cml:singlebond|cml:doublebond|cml:triplebond}}
+ {\xmlindex{#1}{cml:caption}{2}}
+ {\xmlindex{#1}{cml:caption}{1}}
+\stopxmlsetups
+
+\startxmlsetups cml:atom
+ \doCMLtext {
+ \lohi {
+ $\tfxx\xmlatt{#1}{protons}$
+ } {
+ $\tfxx\xmlatt{#1}{weight}$
+ }
+ \xmlflush{#1}
+ \lohi {
+ $\tfxx\xmlatt{#1}{n}$
+ } {
+ $\tfxx\xmlatt{#1}{charge}$%
+ }
+ }
+ {\xmlindex{#1}{cml:caption}{2}}
+ {\xmlindex{#1}{cml:caption}{1}}
+\stopxmlsetups
+
+\startxmlsetups cml:ion
+ \doifelseCMLvariable{#1}{alternative}{b} {
+ \left[
+ \doCMLtext
+ {\doCMLamount{#1}
+ \xmlall{#1}{cml:atom}}
+ {\xmlindex{#1}{cml:caption}{2}}
+ {\xmlindex{#1}{cml:caption}{1}}
+ \right]
+ } {
+ \doCMLtext
+ {\doCMLamount{#1}
+ \xmlall{#1}{cml:atom}}
+ {\xmlindex{#1}{cml:caption}{2}}
+ {\xmlindex{#1}{cml:caption}{1}}
+ }
+ \high {\xmlatt{#1}{charge}}
+\stopxmlsetups
+
+\def\doCMLgives {\xrightarrow}
+\def\doCMLequilibrium{\xleftrightarrow}
+\def\doCMLmesomeric {\xrightoverleftarrow}
+\def\doCMLplus {+}
+\def\doCMLminus {-}
+\def\doCMLequal {=}
+
+\startxmlsetups cml:arrow
+ \quad
+ \executeifdefined{doCML\xmlname{#1}}\doCMLgives{\tf\xmlindex{#1}{cml:caption}{2}}{\tf\xmlindex{#1}{cml:caption}{1}}
+ \quad
+\stopxmlsetups
+
+\startxmlsetups cml:operator
+ \quad
+ \mathop{\executeifdefined{doCML\xmlname{#1}}\doCMLplus}
+ \quad
+\stopxmlsetups
+
+\startxmlsetups cml:bond
+ \executeifdefined{doCML\xmlname{#1}} {
+ \ifcase0\xmlatt{#1}{n}\relax
+ \doCMLsinglebond
+ \or
+ \doCMLdoublebond
+ \or
+ \doCMLtriplebond
+ \fi
+ }
+\stopxmlsetups
+
+\def\doCMLbond
+ {\hrule\s!width\hsize\s!height.1ex\relax}
+
+\def\dodoCMLbond#1#2#3%
+ {\begingroup
+ \setbox\scratchbox\hbox{$M$}%
+ \vbox to \ht\scratchbox
+ {\hsize\wd\scratchbox
+ \vskip.1\wd\scratchbox
+ #1\vfill#2\vfill#3%
+ \vskip.1\wd\scratchbox}%
+ \endgroup}
+
+\def\doCMLsinglebond{\dodoCMLbond\relax \doCMLbond\relax }
+\def\doCMLdoublebond{\dodoCMLbond\doCMLbond\relax \doCMLbond}
+\def\doCMLtriplebond{\dodoCMLbond\doCMLbond\doCMLbond\doCMLbond}
+
+\startxmlsetups cml:structure
+ \startchemical
+ \xmlall{#1}{cml:component}
+ \stopchemical
+\stopxmlsetups
+
+% It makes not much sense to adapt ppchtex to accept different input. Maybe some day.
+
+\startxmlsetups cml:component
+ \expanded {
+ \chemical
+ [\ctxmodulechemml{do_graphic("#1")}]
+ [\ctxmodulechemml{no_graphic("#1")}]
+ }
+\stopxmlsetups
+
+\unexpanded\def\doCMLannotation#1% #2#3% loc caption text
+ {\xmlval{cml:a:l}{#1}{\chemicalright}}% {#2}{#3}}
+
+\xmlmapvalue {cml:a:l} {t} {\chemicaltop}
+\xmlmapvalue {cml:a:l} {b} {\chemicalbottom}
+\xmlmapvalue {cml:a:l} {l} {\chemicalleft}
+\xmlmapvalue {cml:a:l} {r} {\chemicalright}
+\xmlmapvalue {cml:a:l} {lc} {\chemicalleftcentered} % \xmlmapvalue {cml:a:l} {cl} {\chemicalleftcentered}
+\xmlmapvalue {cml:a:l} {rc} {\chemicalrightcentered} % \xmlmapvalue {cml:a:l} {cr} {\chemicalrightcentered}
+\xmlmapvalue {cml:a:l} {tl} {\chemicaltopleft} % \xmlmapvalue {cml:a:l} {lt} {\chemicaltopleft}
+\xmlmapvalue {cml:a:l} {bl} {\chemicalbottomleft} % \xmlmapvalue {cml:a:l} {lb} {\chemicalbottomleft}
+\xmlmapvalue {cml:a:l} {tr} {\chemicaltopright} % \xmlmapvalue {cml:a:l} {rt} {\chemicaltopright}
+\xmlmapvalue {cml:a:l} {br} {\chemicalbottomright} % \xmlmapvalue {cml:a:l} {rb} {\chemicalbottomright}
+\xmlmapvalue {cml:a:l} {lt} {\chemicallefttop} % \xmlmapvalue {cml:a:l} {tl} {\chemicallefttop}
+\xmlmapvalue {cml:a:l} {lb} {\chemicalleftbottom} % \xmlmapvalue {cml:a:l} {bl} {\chemicalleftbottom}
+\xmlmapvalue {cml:a:l} {rt} {\chemicalrighttop} % \xmlmapvalue {cml:a:l} {tr} {\chemicalrighttop}
+\xmlmapvalue {cml:a:l} {rb} {\chemicalrightbottom} % \xmlmapvalue {cml:a:l} {br} {\chemicalrightbottom}
+\xmlmapvalue {cml:a:l} {x} {\chemicaltighttext}
+\xmlmapvalue {cml:a:l} {sl} {\chemicalsmashedleft} % \xmlmapvalue {cml:a:l} {ls} {\chemicalsmashedleft}
+\xmlmapvalue {cml:a:l} {sm} {\chemicalsmashedmiddle} % \xmlmapvalue {cml:a:l} {ms} {\chemicalsmashedmiddle}
+\xmlmapvalue {cml:a:l} {sr} {\chemicalsmashedright} % \xmlmapvalue {cml:a:l} {rs} {\chemicalsmashedright}
+
+\startxmlsetups cml:forever
+ \left[\xmlflush{#1}\right]
+\stopxmlsetups
+
+% \starttext
+% \xmlprocess{main}{cmltest.xml}{xml:process}
+% \stoptext
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/x-ct.lua b/tex/context/modules/mkiv/x-ct.lua
new file mode 100644
index 000000000..9c647e8e7
--- /dev/null
+++ b/tex/context/modules/mkiv/x-ct.lua
@@ -0,0 +1,167 @@
+if not modules then modules = { } end modules ['x-ct'] = {
+ version = 1.001,
+ comment = "companion to x-ct.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- needs testing
+
+local xmlsprint, xmlcprint, xmlfilter, xmlcollected = xml.sprint, xml.cprint, xml.filter, xml.collected
+local format, concat, rep, find = string.format, table.concat, string.rep, string.find
+
+moduledata.ct = moduledata.ct or { }
+
+local halignments = {
+ left = 'l',
+ flushleft = 'l',
+ right = 'r',
+ flushright = 'r',
+ center = 'c',
+ middle = 'c',
+ centre = 'c',
+ justify = '',
+}
+
+local templates = { }
+
+function moduledata.ct.registertabulatetemplate(name,str)
+ templates[name] = str
+end
+
+local function roottemplate(root)
+ local rt = root.at.template
+ if rt then
+ local template = templates[rt]
+ if template then
+ return template
+ else
+ if not find(rt,"|") then
+ rt = gsub(rt,",","|")
+ end
+ if not find(rt,"^|") then rt = "|" .. rt end
+ if not find(rt,"|$") then rt = rt .. "|" end
+ return rt
+ end
+ end
+end
+
+local function specifiedtemplate(root,templatespec)
+ local template = { }
+ for e in xmlcollected(root,templatespec) do
+ local at = e.at
+ local tm = halignments[at.align] or ""
+ if toboolean(at.paragraph) then
+ tm = tm .. "p"
+ end
+ template[#template+1] = tm
+ end
+ if #template > 0 then
+ return "|" .. concat(template,"|") .. "|"
+ else
+ return nil
+ end
+end
+
+local function autotemplate(root,rowspec,cellspec)
+ local max = 0
+ for e in xmlcollected(root,rowspec) do
+ local n = xml.count(e,cellspec)
+ if n > max then max = n end
+ end
+ if max == 2 then
+ return "|l|p|"
+ elseif max > 0 then
+ return "|" .. rep("p|",max)
+ else
+ return nil
+ end
+end
+
+local defaulttemplate = "|l|p|"
+
+function moduledata.ct.tabulate(root,namespace)
+ if not root then
+ return
+ else
+ root = lxml.id(root)
+ end
+
+ local prefix = (namespace or "context") .. ":"
+
+ local templatespec = "/" .. prefix .. "template" .. "/" .. prefix .. "column"
+ local bodyrowspec = "/" .. prefix .. "body" .. "/" .. prefix .. "row"
+ local cellspec = "/" .. prefix .. "cell"
+
+ local template =
+ roottemplate (root) or
+ specifiedtemplate (root,templatespec) or
+ autotemplate (root,bodyrowspec,cellspec) or
+ defaulttemplate
+
+ -- todo: head and foot
+
+ local NC, NR = context.NC, context.NR
+
+ lxml.directives.before(root,'cdx')
+ context.bgroup()
+ lxml.directives.setup(root,'cdx')
+ context.starttabulate { template }
+ for e in xmlcollected(root,bodyrowspec) do
+ NC()
+ for e in xmlcollected(e,cellspec) do
+ xmlcprint(e)
+ NC()
+ end
+ NR()
+ end
+ context.stoptabulate()
+ context.egroup()
+ lxml.directives.after(root,'cdx')
+
+end
+
+-- todo: use content and caption
+
+function moduledata.ct.combination(root,namespace)
+
+ if not root then
+ return
+ else
+ root = lxml.id(root)
+ end
+
+ local prefix = (namespace or "context") .. ":"
+
+ local pairspec = "/" .. prefix .. "pair"
+ local contentspec = "/" .. prefix .. "content" .. "/text()"
+ local captionspec = "/" .. prefix .. "caption" .. "/text()"
+
+ local nx, ny = root.at.nx, root.at.ny
+
+ if not (nx or ny) then
+ nx = xml.count(root,pairspec) or 2
+ end
+ local template = format("%s*%s", nx or 1, ny or 1)
+
+ lxml.directives.before(root,'cdx')
+ context.bgroup()
+ lxml.directives.setup(root,'cdx')
+ context.startcombination { template }
+ for e in xmlcollected(root,pairspec) do
+ -- context.combination(
+ -- function() xmlfilter(e,contentspec) end,
+ -- function() xmlfilter(e,captionspec) end
+ -- )
+ context("{")
+ xmlfilter(e,contentspec)
+ context("}{")
+ xmlfilter(e,captionspec)
+ context("}")
+ end
+ context.stopcombination()
+ context.egroup()
+ lxml.directives.after(root,'cdx')
+
+end
diff --git a/tex/context/modules/mkiv/x-ct.mkiv b/tex/context/modules/mkiv/x-ct.mkiv
new file mode 100644
index 000000000..6a6352f03
--- /dev/null
+++ b/tex/context/modules/mkiv/x-ct.mkiv
@@ -0,0 +1,29 @@
+%D \module
+%D [ file=x-cals,
+%D version=2007.09.05,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\CONTEXT\ Structures,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt XML Macros / Basics}
+
+\startmodule [ct]
+
+\registerctxluafile{x-ct}{}
+
+\startxmlsetups xml:context:process
+ \xmlsetfunction {\xmldocument} {context:tabulate} {moduledata.ct.tabulate}
+ \xmlsetfunction {\xmldocument} {context:combination} {moduledata.ct.combination}
+\stopxmlsetups
+
+\xmlregistersetup{xml:context:process}
+
+\xmlregisterns{context}{context}
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/x-entities.mkiv b/tex/context/modules/mkiv/x-entities.mkiv
new file mode 100644
index 000000000..3dd02118a
--- /dev/null
+++ b/tex/context/modules/mkiv/x-entities.mkiv
@@ -0,0 +1,18 @@
+%D \module
+%D [ file=x-entities,
+%D version=2008.05.29,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\HTML\ entities,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt XML Macros / HTML entities}
+
+\ctxlua{characters.registerentities()}
+
+\endinput
diff --git a/tex/context/modules/mkiv/x-foxet.mkiv b/tex/context/modules/mkiv/x-foxet.mkiv
new file mode 100644
index 000000000..80fe7e500
--- /dev/null
+++ b/tex/context/modules/mkiv/x-foxet.mkiv
@@ -0,0 +1,29 @@
+%D \module
+%D [ file=x-foxet,
+%D version=2004.03.12, % based on earlier experiments
+%D title=\FOXET,
+%D subtitle=Formatting Objects,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Nota bene: I will reimplement formatting object in proper
+%D \MKIV\ code.
+
+\writestatus{foxet}{the mkiv variant is under construction}
+
+%D This module is just a shortcut for:
+
+% fo = basic formatting objects
+% fe = basic formatting extensions
+% fx = extra formatting objects
+% fu = user formatting objects
+% fs = setup
+
+% \usemodule[fo,fe,fx,fu,fs,mathml]
+
+\endinput
diff --git a/tex/context/modules/mkiv/x-html.mkiv b/tex/context/modules/mkiv/x-html.mkiv
new file mode 100644
index 000000000..e1806eb9e
--- /dev/null
+++ b/tex/context/modules/mkiv/x-html.mkiv
@@ -0,0 +1,379 @@
+%D \module
+%D [ file=x-html,
+%D version=2011.02.03, % adapted 2014.11.08
+%D title=\CONTEXT\ Modules,
+%D subtitle=HTML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startmodule[html]
+
+%D Usage:
+%D
+%D \starttyping
+%D \xmlregistersetup{xml:html:basics}
+%D \xmlregistersetup{xml:html:tables}
+%D \stoptyping
+
+% \xmlsetsetup{#1}{(p|span)[@lang]}{xml:html:lang}
+%
+% \startxmlsetups xml:html:lang
+% \begingroup
+% \language[\xmlatt{#1}{lang}]
+% \xmlsetup{#1}{xml:html:\xmltag{#1}}
+% \endgroup
+% \stopxmlsetups
+
+\unprotect
+
+\definehighlight[b] [\c!command=\v!no,\c!style=\v!bold]
+\definehighlight[i] [\c!command=\v!no,\c!style=\v!italic]
+\definehighlight[bi] [\c!command=\v!no,\c!style=\v!bolditalic]
+\definehighlight[em] [\c!command=\v!no,\c!style=\em]
+\definehighlight[tt] [\c!command=\v!no,\c!style=\v!mono]
+\definehighlight[strong][\c!command=\v!no,\c!style=\v!bold]
+\definehighlight[u] [\c!command=\v!no,\c!style=\directsetbar{\v!underbar}]
+\definehighlight[code] [\c!command=\v!no,\c!style=\v!mono]
+\definehighlight[pre] [\c!command=\v!no]
+
+\protect
+
+% todo: pre
+
+\startxmlsetups xml:html:basics
+ \xmlsetsetup{#1}{p|br|b|i|u|em|tt|strong|ul|ol|li|table|thead|tbody|tfoot|tr|td|th|span|img}{xml:html:*}
+ \xmlsetsetup{#1}{b/i}{xml:html:bi}
+ \xmlsetsetup{#1}{i/b}{xml:html:bi}
+ \xmlstripanywhere{#1}{!pre}
+\stopxmlsetups
+
+\startxmlsetups xml:html:tables
+ \xmlsetsetup{#1}{table|thead|tbody|tfoot|tr|td|th}{xml:html:*}
+\stopxmlsetups
+
+\startxmlsetups xml:html:p
+ \xmldoifnotselfempty {#1} {
+ \dontleavehmode
+ \ignorespaces
+ \xmlflush{#1}
+ \removeunwantedspaces
+ }
+ \par
+\stopxmlsetups
+
+\startxmlsetups xml:html:br
+ \crlf
+\stopxmlsetups
+
+\startxmlsetups xml:html:b
+ \directhighlight{b}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:i
+ \directhighlight{i}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:bi
+ \directhighlight{bi}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:em
+ \directhighlight{em}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:tt
+ \directhighlight{tt}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:strong
+ \directhighlight{strong}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:u
+ \directhighlight{u}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:ul
+ \startitemize[packed]
+ \xmlflush{#1}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups xml:html:ol
+ \startitemize[packed,n]
+ \xmlflush{#1}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups xml:html:li
+ \startitem
+ \xmlflush{#1}
+ \stopitem
+\stopxmlsetups
+
+\startxmlsetups xml:html:code
+ \directhighlight{code}{\xmlflushspacewise{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:pre
+ \directhighlight{pre}{\xmlflushspacewise{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:html:span
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:html:img
+ \ifhmode
+ \dontleavehmode
+ \externalfigure[\xmlatt{#1}{src}]
+ \else
+ \startlinecorrection
+ \externalfigure[\xmlatt{#1}{src}]
+ \stoplinecorrection
+ \fi
+\stopxmlsetups
+
+% tables, maybe we need a generic html table module
+%
+% todo: align
+
+% beware, the padding code is somewhat experimental, eventually the
+% table will be done in cld code
+%
+% we can also use \xmlmap for border etc
+
+\starttexdefinition cssgetsinglepadding #1
+ \ctxlua {
+ context((moduledata.css.padding(
+ "#1",
+ \number\dimexpr0.1ex,
+ \number\dimexpr0.01\hsize,
+ \number\dimexpr1ex,
+ \number\dimexpr1em
+ ))) % returns 4 values therefore ()
+ }sp
+\stoptexdefinition
+
+\startxmlsetups xml:html:table
+ \edef\CellPadding{\xmlatt{#1}{cellpadding}}
+ \ifx\CellPadding\empty
+ \edef\CellPadding{.25ex}
+ \else
+ \edef\CellPadding{\cssgetsinglepadding\CellPadding}
+ \fi
+ \startlinecorrection[blank]
+ \doifelse {\xmlatt{#1}{border}} {0} {
+ \bTABLE[frame=off,offset=\CellPadding]
+ \xmlflush{#1}
+ \eTABLE
+ } {
+ \bTABLE[offset=\CellPadding]
+ \xmlflush{#1}
+ \eTABLE
+ }
+ \stoplinecorrection
+\stopxmlsetups
+
+\startxmlsetups xml:html:thead
+ \bTABLEhead
+ \xmlflush{#1}
+ \eTABLEhead
+\stopxmlsetups
+
+\startxmlsetups xml:html:tbody
+ \bTABLEbody
+ \xmlflush{#1}
+ \eTABLEbody
+\stopxmlsetups
+
+\startxmlsetups xml:html:tfoot
+ \bTABLEfoot
+ \xmlflush{#1}
+ \eTABLEfoot
+\stopxmlsetups
+
+\startxmlsetups xml:html:tr
+ \bTR[ny=\xmlattdef{#1}{rowspan}{1}]
+ \xmlflush{#1}
+ \eTR
+\stopxmlsetups
+
+\startxmlsetups xml:html:td
+ \bTD[nx=\xmlattdef{#1}{colspan}{1}]
+ \xmlflush{#1}
+ \eTD
+\stopxmlsetups
+
+\startxmlsetups xml:html:th
+ \bTH[nx=\xmlattdef{#1}{colspan}{1}]
+ \xmlflush{#1}
+ \eTH
+\stopxmlsetups
+
+% \xmlregistersetup{xml:html:basics}
+
+%D For old times sake:
+
+\startxmlsetups xml:setups:common
+ \xmlsetup{#1}{xml:html:basics}
+ \xmlsetup{#1}{xml:html:tables}
+% \ifconditional\qmlcleanuptwo
+% \xmlsetsetup{#1}{html/br[index() == 1]}{xml:noppes:1}
+% \xmlsetsetup{#1}{html/p[index() == lastindex()]/br[index() == lastindex()]}{xml:noppes:2}
+% \xmlsetsetup{#1}{html/br[index() == lastindex()]}{xml:noppes:3}
+% \xmlsetsetup{#1}{br[name(1) == 'img']}{xml:noppes}
+% \xmlsetsetup{#1}{br[name(1) == 'br' and name(2) == 'img']}{xml:noppes}
+% % \xmlsetsetup{#1}{br/following-sibling::img[position()==1]}{xml:noppes}
+% \fi
+\stopxmlsetups
+
+\stopmodule
+
+\continueifinputfile{x-html.mkiv}
+
+\xmlregistersetup{xml:html:basics}
+\xmlregistersetup{xml:html:tables}
+
+\startxmlsetups xml:whatever
+ \xmlsetsetup {#1} {
+ html|body
+ } {xml:html:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{main}{xml:whatever}
+
+\startxmlsetups xml:html:html
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:html:body
+ \xmlflush{#1}
+\stopxmlsetups
+
+\setuphead[subject][page=yes,style=\bfa]
+
+\starttexdefinition ShowExample#1
+ \startsubject[title=#1]
+ \typebuffer[#1]
+ \starttextrule{result}
+ \xmlprocessbuffer{main}{#1}{}
+ \stoptextrule
+ \stopsubject
+\stoptexdefinition
+
+\starttext
+
+\startbuffer[test 1]
+<html><body>
+<p>test</p>
+<p/>
+<p>test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 2]
+<html><body>
+<p>test (hierna een lf)
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 3]
+<html><body>
+<p>test (hierna een lf met lege regel)
+
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 4]
+<html><body>
+<p>test (hierna een lf met twee lege regels)
+
+
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 5]
+<html><body>
+<p>test (hierna br geen lf)<br/> test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 6]
+<html><body>
+<p>test (hierna br met lf)<br/>
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 7]
+<html><body>
+<p>test (hierna br met lf en lege regel)<br/>
+
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 8]
+<html><body>
+<p>test (hierna br met lf en twee lege regels)<br/>
+
+
+test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 9]
+<html><body>
+<p>test (hierna bold) <b>bold</b> test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 10]
+<html><body>
+<p>test (hierna lf met bold)
+<b>bold <u>underlined</u></b> test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 11]
+<html><body>
+<p>test (hierna lf met lege regel en bold)
+
+<b>bold</b> test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 12]
+<html><body>
+<p>test (hierna lf met lege regel en lf in bold)
+
+<b>
+bold
+</b> test</p>
+</body></html>
+\stopbuffer
+
+\startbuffer[test 13]
+<html><body>
+<p>test (hierna lf met lege regel en lf en lege regel in bold)
+
+<b>
+
+bold
+
+</b> test</p>
+</body></html>
+\stopbuffer
+
+\dorecurse{13}{\ShowExample{test #1}}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-ldx.ctx b/tex/context/modules/mkiv/x-ldx.ctx
new file mode 100644
index 000000000..edbffc285
--- /dev/null
+++ b/tex/context/modules/mkiv/x-ldx.ctx
@@ -0,0 +1,23 @@
+<?xml version='1.0' standalone='yes'?>
+
+<ctx:job>
+ <ctx:message>Lua Documentation Generator</ctx:message>
+ <ctx:preprocess>
+ <ctx:processors>
+ <ctx:processor name='ldx'>mtxrun --script x-ldx.lua <ctx:value name='old'/> <ctx:value name='new'/></ctx:processor>
+ </ctx:processors>
+ <ctx:files>
+ <ctx:file processor='ldx'><ctx:value name='old'/></ctx:file>
+ </ctx:files>
+ </ctx:preprocess>
+ <ctx:flags>
+ <ctx:flag>purge</ctx:flag>
+ <ctx:flag>forcexml</ctx:flag>
+ </ctx:flags>
+ <ctx:process>
+ <ctx:resources>
+ <ctx:environment>x-ldx.mkiv</ctx:environment>
+ </ctx:resources>
+ </ctx:process>
+</ctx:job>
+
diff --git a/tex/context/modules/mkiv/x-ldx.lua b/tex/context/modules/mkiv/x-ldx.lua
new file mode 100644
index 000000000..31cbebf13
--- /dev/null
+++ b/tex/context/modules/mkiv/x-ldx.lua
@@ -0,0 +1,341 @@
+if not modules then modules = { } end modules ['x-ldx'] = {
+ version = 1.001,
+ comment = "companion to x-ldx.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- --[[ldx--
+-- <topic>Introduction</topic>
+-- --ldx]]--
+
+--[[ldx--
+<source>Lua Documentation Module</source>
+
+This file is part of the <logo label='context'/> documentation suite and
+itself serves as an example of using <logo label='lua'/> in combination
+with <logo label='tex'/>.
+
+I will rewrite this using lpeg. On the other hand, we cannot expect proper
+<logo label='tex'/> and for educational purposed the syntax might be wrong.
+--ldx]]--
+
+-- there is a nice parser on from http://lua-users.org/wiki/LpegRecipes (by
+-- Patrick Donnelly) but lua crashes when I apply functions to some of the
+-- matches
+
+banner = "version 1.0.1 - 2007+ - PRAGMA ADE / CONTEXT"
+
+--[[
+This script needs a few libraries. Instead of merging the code here
+we can use
+
+<typing>
+mtxrun --internal x-ldx.lua
+</typing>
+
+That way, the libraries included in the runner will be used.
+]]--
+
+-- libraries l-string.lua l-table.lua l-io.lua l-file.lua
+
+-- begin library merge
+-- end library merge
+
+local gsub, find, sub = string.gsub, string.find, string.sub
+local splitstring, emptystring = string.split, string.is_empty
+local concat = table.concat
+
+--[[
+Just a demo comment line. We will handle such multiline comments but
+only when they start and end at the beginning of a line. More rich
+comments are tagged differently.
+]]--
+
+--[[ldx--
+First we define a proper namespace for this module. The <q>l</q> stands for
+<logo label='lua'/>, the <q>d</q> for documentation and the <q>x</q> for
+<logo label='xml'/>.
+--ldx]]--
+
+if not ldx then ldx = { } end
+
+--[[ldx--
+We load the lua file into a table. The entries in this table themselves are
+tables and have keys like <t>code</t> and <t>comment</t>.
+--ldx]]--
+
+function ldx.load(filename)
+ local data = file.readdata(filename)
+ local expr = "%s*%-%-%[%[ldx%-*%s*(.-)%s*%-%-ldx%]%]%-*%s*"
+ local i, j, t = 0, 0, { }
+ while true do
+ local comment, ni
+ ni, j, comment = find(data, expr, j)
+ if not ni then break end
+ t[#t+1] = { code = sub(data, i, ni-1) }
+ t[#t+1] = { comment = comment }
+ i = j + 1
+ end
+ local str = sub(data, i, #data)
+ str = gsub(str, "^%s*(.-)%s*$", "%1")
+ if #str > 0 then
+ t[#t+1] = { code = str }
+ end
+ return t
+end
+
+--[[ldx--
+We will tag keywords so that we can higlight them using a special font
+or color. Users can extend this list when needed.
+--ldx]]--
+
+ldx.keywords = { }
+
+--[[ldx--
+Here come the reserved words:
+--ldx]]--
+
+ldx.keywords.reserved = {
+ ["and"] = 1,
+ ["break"] = 1,
+ ["do"] = 1,
+ ["else"] = 1,
+ ["elseif"] = 1,
+ ["end"] = 1,
+ ["false"] = 1,
+ ["for"] = 1,
+ ["function"] = 1,
+ ["if"] = 1,
+ ["in"] = 1,
+ ["local"] = 1,
+ ["nil"] = 1,
+ ["not"] = 1,
+ ["or"] = 1,
+ ["repeat"] = 1,
+ ["return"] = 1,
+ ["then"] = 1,
+ ["true"] = 1,
+ ["until"] = 1,
+ ["while"] = 1
+}
+
+--[[ldx--
+We need to escape a few tokens. We keep the hash local to the
+definition but set it up only once, hence the <key>do</key>
+construction.
+--ldx]]--
+
+do
+ local e = { [">"] = "&gt;", ["<"] = "&lt;", ["&"] = "&amp;" }
+ function ldx.escape(str)
+ return (gsub(str, "([><&])",e))
+ end
+end
+
+--[[ldx--
+Enhancing the code is a bit tricky due to the fact that we have to
+deal with strings and escaped quotes within these strings. Before we
+mess around with the code, we hide the strings, and after that we
+insert them again. Single and double quoted strings are tagged so
+that we can use a different font to highlight them.
+--ldx]]--
+
+ldx.make_index = true
+
+function ldx.enhance(data) -- i need to use lpeg and then we can properly autoindent -)
+ local e = ldx.escape
+ for k=1,#data do
+ local v = data[k]
+ if v.code then
+ local dqs, sqs, com, cmt, cod = { }, { }, { }, { }, e(v.code)
+ cod = gsub(cod, '\\"', "##d##")
+ cod = gsub(cod, "\\'", "##s##")
+ cod = gsub(cod, "%-%-%[%[.-%]%]%-%-", function(s)
+ cmt[#cmt+1] = s
+ return "<l<<<".. #cmt ..">>>l>"
+ end)
+ cod = gsub(cod, "%-%-([^\n]*)", function(s)
+ com[#com+1] = s
+ return "<c<<<".. #com ..">>>c>"
+ end)
+ cod = gsub(cod, "(%b\"\")", function(s)
+ dqs[#dqs+1] = sub(s,2,-2) or ""
+ return "<d<<<".. #dqs ..">>>d>"
+ end)
+ cod = gsub(cod, "(%b\'\')", function(s)
+ sqs[#sqs+1] = sub(s,2,-2) or ""
+ return "<s<<<".. #sqs ..">>>s>"
+ end)
+ cod = gsub(cod, "(%a+)",function(key)
+ local class = ldx.keywords.reserved[key]
+ if class then
+ return "<key class='" .. class .. "'>" .. key .. "</key>"
+ else
+ return key
+ end
+ end)
+ cod = gsub(cod, "<s<<<(%d+)>>>s>", function(s)
+ return "<sqs>" .. sqs[tonumber(s)] .. "</sqs>"
+ end)
+ cod = gsub(cod, "<d<<<(%d+)>>>d>", function(s)
+ return "<dqs>" .. dqs[tonumber(s)] .. "</dqs>"
+ end)
+ cod = gsub(cod, "<c<<<(%d+)>>>c>", function(s)
+ return "<com>" .. com[tonumber(s)] .. "</com>"
+ end)
+ cod = gsub(cod, "<l<<<(%d+)>>>l>", function(s)
+ return cmt[tonumber(s)]
+ end)
+ cod = gsub(cod, "##d##", "\\\"")
+ cod = gsub(cod, "##s##", "\\\'")
+ if ldx.make_index then
+ local lines = splitstring(cod,"\n")
+ local f = "(<key class='1'>function</key>)%s+([%w%.]+)%s*%("
+ for k=1,#lines do
+ local v = lines[k]
+ -- functies
+ v = gsub(v,f,function(key, str)
+ return "<function>" .. str .. "</function>("
+ end)
+ -- variables
+ v = gsub(v,"^([%w][%w%,%s]-)(=[^=])",function(str, rest)
+ local t = splitstring(str,",%s*")
+ for k=1,#t do
+ t[k] = "<variable>" .. t[k] .. "</variable>"
+ end
+ return concat(t,", ") .. rest
+ end)
+ -- so far
+ lines[k] = v
+ end
+ v.code = concat(lines,"\n")
+ else
+ v.code = cod
+ end
+ end
+ end
+end
+
+--[[ldx--
+We're now ready to save the file in <logo label='xml'/> format. This boils
+down to wrapping the code and comment as well as the whole document. We tag
+lines in the code as such so that we don't need messy <t>CDATA</t> constructs
+and by calculating the indentation we also avoid space troubles. It also makes
+it possible to change the indentation afterwards.
+--ldx]]--
+
+function ldx.as_xml(data) -- ldx: not needed
+ local t, cmode = { }, false
+ t[#t+1] = "<?xml version='1.0' standalone='yes'?>\n"
+ t[#t+1] = "\n<document xmlns:ldx='http://www.pragma-ade.com/schemas/ldx.rng' xmlns='http://www.pragma-ade.com/schemas/ldx.rng'>\n"
+ for k=1,#data do
+ local v = data[k]
+ if v.code and not emptystring(v.code) then
+ t[#t+1] = "\n<code>\n"
+ local split = splitstring(v.code,"\n")
+ for k=1,#split do -- make this faster
+ local v = split[k]
+ local a, b = find(v,"^(%s+)")
+ if v then v = gsub(v,"[\n\r ]+$","") end
+ if a and b then
+ v = sub(v,b+1,#v)
+ if cmode then
+ t[#t+1] = "<line comment='yes' n='" .. b .. "'>" .. v .. "</line>\n"
+ else
+ t[#t+1] = "<line n='" .. b .. "'>" .. v .. "</line>\n"
+ end
+ elseif emptystring(v) then
+ if cmode then
+ t[#t+1] = "<line comment='yes'/>\n"
+ else
+ t[#t+1] = "<line/>\n"
+ end
+ elseif find(v,"^%-%-%[%[") then
+ t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n"
+ cmode= true
+ elseif find(v,"^%]%]%-%-") then
+ t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n"
+ cmode= false
+ elseif cmode then
+ t[#t+1] = "<line comment='yes'>" .. v .. "</line>\n"
+ else
+ t[#t+1] = "<line>" .. v .. "</line>\n"
+ end
+ end
+ t[#t+1] = "</code>\n"
+ elseif v.comment then
+ t[#t+1] = "\n<comment>\n" .. v.comment .. "\n</comment>\n"
+ else
+ -- cannot happen
+ end
+ end
+ t[#t+1] = "\n</document>\n"
+ return concat(t,"")
+end
+
+--[[ldx--
+Saving the result is a trivial effort.
+--ldx]]--
+
+function ldx.save(filename,data)
+ file.savedata(filename,ldx.as_xml(data))
+end
+
+--[[ldx--
+The next function wraps it all in one call:
+--ldx]]--
+
+function ldx.convert(luaname,ldxname)
+ if not file.is_readable(luaname) then
+ luaname = luaname .. ".lua"
+ end
+ if file.is_readable(luaname) then
+ if not ldxname then
+ ldxname = file.replacesuffix(luaname,"ldx")
+ end
+ local data = ldx.load(luaname)
+ if data then
+ ldx.enhance(data)
+ if ldxname ~= luaname then
+ ldx.save(ldxname,data)
+ end
+ end
+ end
+end
+
+--[[ldx--
+This module can be used directly:
+
+<typing>
+mtxrun --internal x-ldx somefile.lua
+</typing>
+
+will produce an ldx file that can be processed with <logo label='context'/>
+by running:
+
+<typing>
+context --use=x-ldx --forcexml somefile.ldx
+</typing>
+
+You can do this in one step by saying:
+
+<typing>
+context --ctx=x-ldx somefile.lua
+</typing>
+
+This will trigger <logo label='context'/> into loading the mentioned
+<logo label='ctx'/> file. That file describes the conversion as well
+as the module to be used.
+
+The main conversion call is:
+--ldx]]--
+
+-- todo: assume usage of "mtxrun --script x-ldx", maybe make it mtx-ldx
+
+if environment.files and environment.files[1] then
+ ldx.convert(environment.files[1],environment.files[2])
+end
+
+--~ exit(1)
diff --git a/tex/context/modules/mkiv/x-ldx.mkiv b/tex/context/modules/mkiv/x-ldx.mkiv
new file mode 100644
index 000000000..0156f2c55
--- /dev/null
+++ b/tex/context/modules/mkiv/x-ldx.mkiv
@@ -0,0 +1,196 @@
+%D \module
+%D [ file=x-ldx,
+%D version=2008.06.03,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Lua Source Pretty Printing,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% this will become an extra
+
+\setupxml[default=hidden]
+
+\usemodule[x][mathml]
+\usemodule[abr-02]
+
+\xmlregistersetup{xml:mml:define}
+\xmlregistersetup{xml:ldx:define}
+
+\xmlregisterns{ldx}{ldx}
+
+\startxmlsetups xml:ldx:define
+ \xmlsetsetup {#1} {ldx:*} {ldx:*}
+\stopxmlsetups
+
+% % %
+
+\startxmlsetups ldx:p
+ \xmlflush{#1}\par
+\stopxmlsetups
+
+\startxmlsetups ldx:source
+ \source{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups ldx:key
+ \dontleavehmode{\bf\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups ldx:variable
+ \xmlflush{#1}
+% \expanded{\variable{\xmlflush{#1}}}
+\stopxmlsetups
+
+\startxmlsetups ldx:function
+ \dontleavehmode{\bf function}\space\xmlflush{#1}
+% \expanded{\function{\xmlflush{#1}}}
+\stopxmlsetups
+
+\startxmlsetups ldx:com
+ \dontleavehmode{\tt--\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups ldx:document
+ \page
+ \xmlflush{#1}
+ \determineregistercharacteristics[function]
+ \startmode[*register]
+ \testpage[4]
+ \extra{Functions}
+ \placeregister[function]
+ \stopmode
+ \determineregistercharacteristics[variable]
+ \startmode[*register]
+ \testpage[4]
+ \extra{Variables}
+ \placeregister[variable]
+ \stopmode
+\stopxmlsetups
+
+\newcounter\CommentCounter
+
+\startxmlsetups ldx:comment
+ \blank
+ \doglobal\increment\CommentCounter
+ \margintitle{\bf\CommentCounter}
+ \xmlflush{#1}
+ \blank
+\stopxmlsetups
+
+\startxmlsetups ldx:dqs
+ \dontleavehmode\bgroup\tt"\xmlflush{#1}"\egroup
+\stopxmlsetups
+
+\startxmlsetups ldx:sqs
+ \dontleavehmode\bgroup\tt'\xmlflush{#1}'\egroup
+\stopxmlsetups
+
+\startxmlsetups ldx:code
+ \startpacked
+ \xmlflush{#1}\relax
+ \stoppacked
+\stopxmlsetups
+
+\startxmlsetups ldx:lines
+ \startpacked
+ \xmlflush{#1}
+ \stoppacked
+\stopxmlsetups
+
+\startxmlsetups ldx:line
+ \doifelsenothing {\xmlflush{#1}} {
+ \xmlflush{#1}\crlf
+ } {
+ \dontleavehmode \hbox to \hsize \bgroup
+ \strut
+ \hskip.25\dimexpr\xmlattdef{#1}{n}{0}em\relax\relax % extra relax needed !
+ \doif {\xmlatt{#1}{comment}} {yes} {\tt}
+ \xmlflush{#1}
+ \hss
+ \egroup
+ \endgraf
+ }
+\stopxmlsetups
+
+\startxmlsetups ldx:logo
+ \uppercasestring\xmlatt{#1}{label}\xmlatt{#1}{name}\to\ascii
+ \ifx\ascii\empty\else\getvalue{\ascii}\fi
+\stopxmlsetups
+
+\startxmlsetups ldx:l
+ \uppercasestring\xmlatt{#1}{l}\xmlatt{#1}{n}\to\ascii
+ \ifx\ascii\empty\else\getvalue{\ascii}\fi
+\stopxmlsetups
+
+\startxmlsetups ldx:typing
+ \blank
+ \startpacked \tt
+ \xmlverbatim{#1}
+ \stoppacked
+ \blank
+\stopxmlsetups
+
+\startxmlsetups ldx:type
+ \dontleavehmode{\tt\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups ldx:t
+ \dontleavehmode{\tt\xmlflush{#1}}
+\stopxmlsetups
+
+% key -> kw
+% dqs -> dq
+% sqs -> sq
+% line -> ln
+% code -> cd
+% comment -> tx (text)
+
+\definetypeface[mainfacenormal] [ss][sans] [iwona] [default]
+\definetypeface[mainfacenormal] [rm][serif][palatino] [default]
+\definetypeface[mainfacenormal] [tt][mono] [modern] [default][rscale=1] % 1.1
+\definetypeface[mainfacenormal] [mm][math] [iwona] [default][encoding=default]
+
+\definetypeface[mainfacemedium] [ss][sans] [iwona-medium][default]
+\definetypeface[mainfacenormal] [rm][serif][palatino] [default]
+\definetypeface[mainfacemedium] [tt][mono] [modern] [default][rscale=1] % 1.1
+\definetypeface[mainfacemedium] [mm][math] [iwona-medium][default][encoding=default]
+
+\definetypeface[mainfacenarrowtt][tt][mono] [modern-cond] [default][rscale=1] % 1.1
+
+\setupbodyfont
+ [mainfacenormal,11pt]
+
+\setupwhitespace
+ [big]
+
+\defineregister[function][functions]
+\defineregister[variable][variables]
+
+\definehead[source][subject]
+\definehead[extra] [subsubject]
+\definehead[topic] [subsubsubject]
+
+\setuphead
+ [source]
+ [style=\bfb]
+
+\setuphead
+ [extra]
+ [style=\bfa]
+
+\setuphead
+ [topic]
+ [style=\bf]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ backspace=2cm,
+ topspace=2cm]
+
+\endinput
diff --git a/tex/context/modules/mkiv/x-math-svg.lua b/tex/context/modules/mkiv/x-math-svg.lua
new file mode 100644
index 000000000..8a6288167
--- /dev/null
+++ b/tex/context/modules/mkiv/x-math-svg.lua
@@ -0,0 +1,176 @@
+if not modules then modules = { } end modules ['x-math-svg'] = {
+ version = 1.001,
+ comment = "companion to x-math-svg.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local tostring, type, next = tostring, type, next
+local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs
+
+local xmlfirst = xml.first
+local xmlconvert = xml.convert
+local xmlload = xml.load
+local xmlsave = xml.save
+local xmlcollected = xml.collected
+local xmldelete = xml.delete
+
+local loadtable = table.load
+local savetable = table.save
+
+local replacesuffix = file.replacesuffix
+local addsuffix = file.addsuffix
+local removefile = os.remove
+local isfile = lfs.isfile
+
+local formatters = string.formatters
+
+moduledata = moduledata or table.setmetatableindex("table")
+local svgmath = moduledata.svgmath -- autodefined
+
+local namedata = { }
+local pagedata = { }
+
+local statusname = "x-math-svg-status.lua"
+local pdfname = "x-math-svg.pdf"
+
+local pdftosvg = os.which("mudraw")
+
+local f_make_tex = formatters[ [[context --global kpse:x-math-svg.mkvi --inputfile="%s" --svgstyle="%s" --batch --noconsole --once --purgeall]] ]
+local f_make_svg = formatters[ [[mudraw -o "math-%%d.svg" "%s" 1-9999]] ]
+
+----- f_inline = formatters[ [[<div class='math-inline' style='vertical-align:%p'></div>]] ]
+local f_inline = formatters[ [[<div class='math-inline'></div>]] ]
+local f_display = formatters[ [[<div class='math-display'></div>]] ]
+local f_style = formatters[ [[vertical-align:%p]] ]
+
+local f_math_tmp = formatters[ [[math-%i]] ]
+
+function svgmath.process(filename)
+ if not filename then
+ -- no filename given
+ return
+ elseif not isfile(filename) then
+ -- invalid filename
+ return
+ end
+ local index = 0
+ local page = 0
+ local blobs = { }
+ local root = xmlload(filename)
+ for mth in xmlcollected(root,"math") do
+ index = index + 1
+ local blob = tostring(mth)
+ if blobs[blob] then
+ context.ReuseSVGMath(index,blobs[blob])
+ else
+ page = page + 1
+ buffers.assign(f_math_tmp(page),blob)
+ context.MakeSVGMath(index,page,mth.at.display)
+ blobs[blob] = page
+ end
+ end
+ context(function()
+ -- for tracing purposes:
+ for mathdata, pagenumber in next, blobs do
+ local p = pagedata[pagenumber]
+ p.mathml = mathdata
+ p.number = pagenumber
+ end
+ --
+ savetable(statusname, {
+ pagedata = pagedata,
+ namedata = namedata,
+ })
+ end)
+end
+
+function svgmath.register(index,page,specification)
+ if specification then
+ pagedata[page] = specification
+ end
+ namedata[index] = page
+end
+
+function svgmath.convert(filename,svgstyle)
+ if not filename then
+ -- no filename given
+ return false, "no filename"
+ elseif not isfile(filename) then
+ -- invalid filename
+ return false, "invalid filename"
+ elseif not pdftosvg then
+ return false, "mudraw is not installed"
+ end
+
+ os.execute(f_make_tex(filename,svgstyle))
+
+ local data = loadtable(statusname)
+ if not data then
+ -- invalid tex run
+ return false, "invalid tex run"
+ elseif not next(data) then
+ return false, "no converson needed"
+ end
+
+ local pagedata = data.pagedata
+ local namedata = data.namedata
+
+ os.execute(f_make_svg(pdfname))
+
+ local root = xmlload(filename)
+ local index = 0
+ local done = { }
+ local unique = 0
+
+ local between = (1-P("<"))^1/""
+ local strip = Cs((
+ (P("<text") * ((1-P("</text>"))^1) * P("</text>")) * between^0 / "" +
+ P(">") * between +
+ P(1)
+ )^1)
+
+ for mth in xmlcollected(root,"m:math") do
+ index = index + 1
+ local page = namedata[index]
+ if done[page] then
+ mth.__p__.dt[mth.ni] = done[page]
+ else
+ local info = pagedata[page]
+ local depth = info.depth
+ local mode = info.mode
+ local svgname = addsuffix(f_math_tmp(page),"svg")
+ local action = mode == "inline" and f_inline or f_display
+ -- local x_div = xmlfirst(xmlconvert(action(-depth)),"/div")
+ local x_div = xmlfirst(xmlconvert(action()),"/div")
+ local svgdata = io.loaddata(svgname)
+ if not svgdata or svgdata == "" then
+ print("error in:",svgname,tostring(mth))
+ else
+ -- svgdata = string.gsub(svgdata,">%s<","")
+ svgdata = lpegmatch(strip,svgdata)
+ local x_svg = xmlfirst(xmlconvert(svgdata),"/svg")
+ -- xmldelete(x_svg,"text")
+if mode == "inline" then
+ x_svg.at.style = f_style(-depth)
+end
+
+ x_div.dt = { x_svg }
+ mth.__p__.dt[mth.ni] = x_div -- use helper
+ end
+ done[page] = x_div
+ unique = unique + 1
+ end
+ end
+
+-- for k, v in next, data do
+-- removefile(addsuffix(k,"svg"))
+-- end
+-- removefile(statusname)
+-- removefile(pdfname)
+
+ xmlsave(root,filename)
+
+ return true, index, unique
+end
diff --git a/tex/context/modules/mkiv/x-mathml-basics.mkiv b/tex/context/modules/mkiv/x-mathml-basics.mkiv
new file mode 100644
index 000000000..e166995b0
--- /dev/null
+++ b/tex/context/modules/mkiv/x-mathml-basics.mkiv
@@ -0,0 +1,276 @@
+% macros=mkvi
+
+% makes sense (but rel vs op ...):
+
+% \unexpanded\def\stackrel#1#2{\mathematics{\mathop{\let\limits\relax\mover{#2}{#1}}}}
+
+% this can become a core helper
+
+% bwe could do all of them in lua
+
+\startluacode
+local find = string.find
+local lpegmatch = lpeg.match
+
+local splitter = lpeg.Ct(lpeg.C(lpeg.patterns.nestedbraces + lpeg.patterns.utf8character)^1)
+
+function commands.xmfenced(left,middle,right,content)
+ local l = left ~= "" and left or "("
+ local r = right ~= "" and right or ")"
+ local m = middle ~= "" and middle and lpegmatch(splitter,middle) or { "," }
+ local c = find(content,"{") and lpegmatch(splitter,content) or { content }
+ local n = #c
+ if n > 1 then
+ context("\\left%s",l)
+ for i=1,n do
+ if i > 1 then
+ context("%s %s",m[i] or m[#m],c[i])
+ else
+ context(c[i])
+ end
+ end
+ context("\\right%s",r)
+ else
+ context("\\left%s %s \\right%s",l,content,r)
+ end
+end
+
+\stopluacode
+
+\unprotect
+
+\unexpanded\def\mexecuteifdefined#1%
+ {\ifx#1\empty
+ \expandafter\secondoftwoarguments
+ \else\ifcsname#1\endcsname
+ \doubleexpandafter\firstoftwoarguments
+ \else
+ \doubleexpandafter\secondoftwoarguments
+ \fi\fi
+ {\csname#1\endcsname}}
+
+% mrow
+
+\let\mrow\mathematics
+
+% msub msup msubsup
+
+\starttexdefinition msub #1#2
+ \mathematics {
+ #1_{#2}
+ }
+\stoptexdefinition
+
+\starttexdefinition msup #1#2
+ \mathematics {
+ #1^{#2}
+ }
+\stoptexdefinition
+
+\starttexdefinition msubsup #1#2#3
+ \mathematics {
+ #1_{#2}^{#3}
+ }
+\stoptexdefinition
+
+% mn mo mi
+
+\let\mn\mathematics
+\let\mo\mathematics
+\let\mi\mathematics
+
+% ms mtext
+
+\starttexdefinition ms #1
+ \text {
+ "#1"
+ }
+\stoptexdefinition
+
+\starttexdefinition mtext #1
+ \text {
+ #1
+ }
+\stoptexdefinition
+
+% mover
+
+\starttexdefinition unexpanded moverabove #1
+ \edef\movercommand{\utfmathfiller\movertoken}
+ \mexecuteifdefined\movercommand {#1} \relax
+\stoptexdefinition
+\starttexdefinition unexpanded moverbase #1
+ \edef\mbasecommand{\utfmathfiller\mbasetoken}
+ \mexecuteifdefined\mbasecommand {#1}
+ \relax
+\stoptexdefinition
+\starttexdefinition unexpanded moverbasefiller #1#2
+ \edef\mbasecommand{e\utfmathcommandfiller\mbasetoken}
+ \mexecuteifdefined\mbasecommand \relax {#2} {}
+\stoptexdefinition
+\starttexdefinition unexpanded moveraccent #1#2
+ \edef\movercommand{\utfmathcommandabove\movertoken}
+ \mexecuteifdefined\movercommand \relax {#1}
+\stoptexdefinition
+\starttexdefinition unexpanded movertext #1#2
+ % \mathtriplet {\mathstylehbox{#1}} {#2} {}
+ \mathtriplet {\mathematics{#1}} {#2} {}
+\stoptexdefinition
+\starttexdefinition unexpanded moveraccentchecker #1#2
+ \edef\movertoken{\tochar{#2}}
+ \doifelseutfmathabove\movertoken \moveraccent \movertext {#1}{#2}
+\stoptexdefinition
+
+\starttexdefinition unexpanded mover #1#2
+ \mathematics {
+ \edef\mbasetoken{\tochar{#1}}
+ \doifelseutfmathfiller\mbasetoken \moverbasefiller \moveraccentchecker {#1}{#2}
+ }
+\stoptexdefinition
+
+% munder
+
+\starttexdefinition unexpanded munderbelow #1
+ \edef\mundercommand{\utfmathfiller\mundertoken}
+ \mexecuteifdefined\mundercommand {#1} \relax
+\stoptexdefinition
+\starttexdefinition unexpanded munderbase #1
+ \edef\mbasecommand{\utfmathfiller\mbasetoken}
+ \mexecuteifdefined\mbasecommand {#1}
+ \relax
+\stoptexdefinition
+\starttexdefinition unexpanded munderbasefiller #1#2
+ \edef\mbasecommand{e\utfmathcommandfiller\mbasetoken}
+ \mexecuteifdefined\mbasecommand \relax {#2} {}
+\stoptexdefinition
+\starttexdefinition unexpanded munderaccent #1#2
+ \edef\mundercommand{\utfmathcommandbelow\mundertoken}
+ \mexecuteifdefined\mundercommand \relax {#1}
+\stoptexdefinition
+\starttexdefinition unexpanded mundertext #1#2
+ % \mathtriplet {\mathstylehbox{#1}} {} {#2}
+ \mathtriplet {\mathematics{#1}} {} {#2}
+\stoptexdefinition
+\starttexdefinition unexpanded munderaccentchecker #1#2
+ \edef\mundertoken{\tochar{#2}}
+ \doifelseutfmathbelow\mundertoken \munderaccent \mundertext {#1}{#2}
+\stoptexdefinition
+
+\starttexdefinition unexpanded munder #1#2
+ \mathematics {
+ \edef\mbasetoken{\tochar{#1}}
+ \doifelseutfmathfiller\mbasetoken \munderbasefiller \munderaccentchecker {#1}{#2}
+ }
+\stoptexdefinition
+
+% munderover
+
+% mfenced
+
+% \mfenced{x,y}
+% \mfenced{{x}{y}}
+% \mfenced[separators]{{x}{y}}
+% \mfenced[left][right]{{x}{y}}
+% \mfenced[left][separators][right]{{x}{y}}
+
+\starttexdefinition unexpanded mfenced
+ \dotripleempty\do_mfenced
+\stoptexdefinition
+
+\starttexdefinition unexpanded do_mfenced [#1][#2][#3]#4
+ \mathematics {
+ \ctxcommand{xmfenced(
+ \ifthirdargument "#1","#2","#3"\else
+ \ifsecondargument "#1",",","#2"\else
+ \iffirstargument "(","#1",")"\else
+ "(",",",")"\fi\fi\fi
+ ,"#4")}
+ }
+\stoptexdefinition
+
+% mfrac
+
+\starttexdefinition unexpanded mfrac #1#2
+ \mathematics {
+ \frac{#1}{#2}
+ }
+\stoptexdefinition
+
+% mroot msqrt
+
+\starttexdefinition unexpanded mroot #1#2
+ \mathematics {
+ \sqrt[#1]{#2}
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded msqrt #1
+ \mathematics {
+ \sqrt{#1}
+ }
+\stoptexdefinition
+
+% menclose
+
+% merror
+
+% mglyph
+
+% mmultiscripts
+
+% mpadded
+
+% mphantom
+
+% mspace
+
+% mstyle
+
+% mtable mtr mlabeledtr mtd
+
+% maction
+
+% semantics
+
+\protect
+
+\continueifinputfile{x-mathml-basics.mkiv}
+
+\starttext
+
+$\mfenced{1+a}$\par
+$\mfenced[,]{1+a}$\par
+$\mfenced[,]{{1+a}{1+b}}$\par
+
+% $\mover{←}{test}$\par
+% $\mover{\utfchar{"2190}}{test}$\par
+% $\mover{e:leftarrow}{test}$\par
+% $\mover{x:2190}{test}$\par
+
+% $\mover{test}{⏞}$\par
+% $\mover{test}{\utfchar{"23DE}}$\par
+% $\mover{test}{e:overbrace}$\par
+% $\mover{test}{x:23DE}$\par
+% $\mover{test}{over}$\par
+
+% \mover{test}{⏞}\par
+% \mover{test}{\utfchar{"23DE}}\par
+% \mover{test}{e:overbrace}\par
+% \mover{test}{x:23DE}\par
+
+% $\munder{←}{test}$\par
+% $\munder{\utfchar{"2190}}{test}$\par
+% $\munder{e:leftarrow}{test}$\par
+% $\munder{x:2190}{test}$\par
+
+% $\munder{test}{⏟}$\par
+% $\munder{test}{\utfchar{"23DF}}$\par
+% $\munder{test}{e:underbrace}$\par
+% $\munder{test}{x:23DF}$\par
+% $\munder{test}{under}$\par
+
+% \math{{\msup{x}{2}\mo{+}\mn{2}\mi{x}\mo{+}\mi{b}}}
+
+% \mrow{\msup{x}{2}\mo{+}\mn{2}\mi{x}\mo{+}\mi{b}}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-mathml-html.mkiv b/tex/context/modules/mkiv/x-mathml-html.mkiv
new file mode 100644
index 000000000..2ac7d3cba
--- /dev/null
+++ b/tex/context/modules/mkiv/x-mathml-html.mkiv
@@ -0,0 +1,40 @@
+%D \modul
+%D [ file=x-mathml,
+%D version=2014.05.18,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\MATHML\ embedded HTML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% maybe some more
+
+\startmodule [mathml-html]
+
+\startxmlsetups mml:html:b
+ \bold{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:html:i
+ \italic{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:html:tt
+ \mono{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:html:em
+ \emphasized{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:html
+ \xmlsetsetup{#1}{mml:b|mml:i|mml:tt|mml:em}{mml:html:*}
+\stopxmlsetups
+
+\xmlregistersetup{mml:html}
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/x-mathml.lua b/tex/context/modules/mkiv/x-mathml.lua
new file mode 100644
index 000000000..50369407f
--- /dev/null
+++ b/tex/context/modules/mkiv/x-mathml.lua
@@ -0,0 +1,898 @@
+if not modules then modules = { } end modules ['x-mathml'] = {
+ version = 1.001,
+ comment = "companion to x-mathml.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This needs an upgrade to the latest greatest mechanisms. But ... it
+-- probably doesn't pay back as no mathml support ever did.
+
+local type, next = type, next
+local formatters, lower, find, gsub, match = string.formatters, string.lower, string.find, string.gsub, string.match
+local strip = string.strip
+local xmlsprint, xmlcprint, xmltext, xmlcontent, xmlempty = xml.sprint, xml.cprint, xml.text, xml.content, xml.empty
+local lxmlcollected, lxmlfilter = lxml.collected, lxml.filter
+local getid = lxml.getid
+local utfchar, utfcharacters, utfvalues, utfsplit, utflen = utf.char, utf.characters, utf.values, utf.split, utf.len
+local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
+local P, Cs = lpeg.P, lpeg.Cs
+
+local mathml = { }
+moduledata.mathml = mathml
+lxml.mathml = mathml -- for the moment
+
+local context = context
+
+local ctx_enabledelimiter = context.enabledelimiter
+local ctx_disabledelimiter = context.disabledelimiter
+local ctx_xmlflush = context.xmlflush -- better xmlsprint
+
+local ctx_halign = context.halign
+local ctx_noalign = context.noalign
+local ctx_bgroup = context.bgroup
+local ctx_egroup = context.egroup
+local ctx_crcr = context.crcr
+
+local ctx_bTABLE = context.bTABLE
+local ctx_eTABLE = context.eTABLE
+local ctx_bTR = context.bTR
+local ctx_eTR = context.eTR
+local ctx_bTD = context.bTD
+local ctx_eTD = context.eTD
+
+local ctx_mn = context.mn
+local ctx_mi = context.mi
+local ctx_mo = context.mo
+local ctx_startimath = context.startimath
+local ctx_ignorespaces = context.ignorespaces
+local ctx_removeunwantedspaces = context.removeunwantedspaces
+local ctx_stopimath = context.stopimath
+
+local ctx_mmlapplycsymbol = context.mmlapplycsymbol
+
+local ctx_mathopnolimits = context.mathopnolimits
+local ctx_left = context.left
+local ctx_right = context.right
+
+-- an alternative is to remap to private codes, where we can have
+-- different properties .. to be done; this will move and become
+-- generic; we can then make the private ones active in math mode
+
+-- todo: handle opening/closing mo's here ... presentation mml is such a mess ...
+
+characters.registerentities()
+
+local doublebar = utfchar(0x2016)
+
+local n_replacements = {
+-- [" "] = utfchar(0x2002), -- "&textspace;" -> tricky, no &; in mkiv
+ ["."] = "{.}",
+ [","] = "{,}",
+ [" "] = "",
+}
+
+local l_replacements = { -- in main table
+ ["|"] = "\\mmlleftdelimiter\\vert",
+ ["{"] = "\\mmlleftdelimiter\\lbrace",
+ ["("] = "\\mmlleftdelimiter(",
+ ["["] = "\\mmlleftdelimiter[",
+ ["<"] = "\\mmlleftdelimiter<",
+ [doublebar] = "\\mmlleftdelimiter\\Vert",
+}
+local r_replacements = { -- in main table
+ ["|"] = "\\mmlrightdelimiter\\vert",
+ ["}"] = "\\mmlrightdelimiter\\rbrace",
+ [")"] = "\\mmlrightdelimiter)",
+ ["]"] = "\\mmlrightdelimiter]",
+ [">"] = "\\mmlrightdelimiter>",
+ [doublebar] = "\\mmlrightdelimiter\\Vert",
+}
+
+-- todo: play with asciimode and avoid mmlchar
+
+-- we can use the proper names now! todo
+
+local o_replacements = { -- in main table
+ ["@l"] = "\\mmlleftdelimiter.",
+ ["@r"] = "\\mmlrightdelimiter.",
+ ["{"] = "\\mmlleftdelimiter \\lbrace",
+ ["}"] = "\\mmlrightdelimiter\\rbrace",
+ ["|"] = "\\mmlleftorrightdelimiter\\vert",
+ -- ["."] = "\\mmlleftorrightdelimiter.",
+ ["/"] = "\\mmlleftorrightdelimiter\\solidus",
+ [doublebar] = "\\mmlleftorrightdelimiter\\Vert",
+ ["("] = "\\mmlleftdelimiter(",
+ [")"] = "\\mmlrightdelimiter)",
+ ["["] = "\\mmlleftdelimiter[",
+ ["]"] = "\\mmlrightdelimiter]",
+ -- ["<"] = "\\mmlleftdelimiter<",
+ -- [">"] = "\\mmlrightdelimiter>",
+ ["#"] = "\\mmlchar{35}",
+ ["$"] = "\\mmlchar{36}", -- $
+ ["%"] = "\\mmlchar{37}",
+ ["&"] = "\\mmlchar{38}",
+ ["^"] = "\\mmlchar{94}{}", -- strange, sometimes luatex math sees the char instead of \char
+ ["_"] = "\\mmlchar{95}{}", -- so we need the {}
+ ["~"] = "\\mmlchar{126}",
+ [" "] = "",
+ ["°"] = "^\\circ", -- hack
+
+ -- [utfchar(0xF103C)] = "\\mmlleftdelimiter<",
+ [utfchar(0xF1026)] = "\\mmlchar{38}",
+ [utfchar(0x02061)] = "", -- function applicator sometimes shows up in font
+ -- [utfchar(0xF103E)] = "\\mmlleftdelimiter>",
+ -- [utfchar(0x000AF)] = '\\mmlchar{"203E}', -- 0x203E
+}
+
+local simpleoperatorremapper = utf.remapper(o_replacements)
+
+--~ languages.data.labels.functions
+
+local i_replacements = {
+ ["sin"] = "\\sin",
+ ["cos"] = "\\cos",
+ ["abs"] = "\\abs",
+ ["arg"] = "\\arg",
+ ["codomain"] = "\\codomain",
+ ["curl"] = "\\curl",
+ ["determinant"] = "\\det",
+ ["divergence"] = "\\div",
+ ["domain"] = "\\domain",
+ ["gcd"] = "\\gcd",
+ ["grad"] = "\\grad",
+ ["identity"] = "\\id",
+ ["image"] = "\\image",
+ ["lcm"] = "\\lcm",
+ ["lim"] = "\\lim",
+ ["max"] = "\\max",
+ ["median"] = "\\median",
+ ["min"] = "\\min",
+ ["mode"] = "\\mode",
+ ["mod"] = "\\mod",
+ ["polar"] = "\\Polar",
+ ["exp"] = "\\exp",
+ ["ln"] = "\\ln",
+ ["log"] = "\\log",
+ ["sin"] = "\\sin",
+ ["arcsin"] = "\\arcsin",
+ ["sinh"] = "\\sinh",
+ ["arcsinh"] = "\\arcsinh",
+ ["cos"] = "\\cos",
+ ["arccos"] = "\\arccos",
+ ["cosh"] = "\\cosh",
+ ["arccosh"] = "\\arccosh",
+ ["tan"] = "\\tan",
+ ["arctan"] = "\\arctan",
+ ["tanh"] = "\\tanh",
+ ["arctanh"] = "\\arctanh",
+ ["cot"] = "\\cot",
+ ["arccot"] = "\\arccot",
+ ["coth"] = "\\coth",
+ ["arccoth"] = "\\arccoth",
+ ["csc"] = "\\csc",
+ ["arccsc"] = "\\arccsc",
+ ["csch"] = "\\csch",
+ ["arccsch"] = "\\arccsch",
+ ["sec"] = "\\sec",
+ ["arcsec"] = "\\arcsec",
+ ["sech"] = "\\sech",
+ ["arcsech"] = "\\arcsech",
+ [" "] = "",
+
+ ["false"] = "{\\mathrm false}",
+ ["notanumber"] = "{\\mathrm NaN}",
+ ["otherwise"] = "{\\mathrm otherwise}",
+ ["true"] = "{\\mathrm true}",
+ ["declare"] = "{\\mathrm declare}",
+ ["as"] = "{\\mathrm as}",
+}
+
+-- we could use a metatable or when accessing fallback on the
+-- key but at least we now have an overview
+
+local csymbols = {
+ arith1 = {
+ lcm = "lcm",
+ big_lcm = "lcm",
+ gcd = "gcd",
+ big_gcd = "big_gcd",
+ plus = "plus",
+ unary_minus = "minus",
+ minus = "minus",
+ times = "times",
+ divide = "divide",
+ power = "power",
+ abs = "abs",
+ root = "root",
+ sum = "sum",
+ product = "product",
+ },
+ fns = {
+ domain = "domain",
+ range = "codomain",
+ image = "image",
+ identity = "ident",
+ -- left_inverse = "",
+ -- right_inverse = "",
+ inverse = "inverse",
+ left_compose = "compose",
+ lambda = "labmda",
+ },
+ linalg1 = {
+ vectorproduct = "vectorproduct",
+ scalarproduct = "scalarproduct",
+ outerproduct = "outerproduct",
+ transpose = "transpose",
+ determinant = "determinant",
+ vector_selector = "selector",
+ -- matrix_selector = "matrix_selector",
+ },
+ logic1 = {
+ equivalent = "equivalent",
+ ["not"] = "not",
+ ["and"] = "and",
+ -- big_and = "",
+ ["xor"] = "xor",
+ -- big_xor = "",
+ ["or"] = "or",
+ -- big-or = "",
+ implies = "implies",
+ ["true"] = "true",
+ ["false"] = "false",
+ },
+ nums1 = {
+ -- based_integer = "based_integer"
+ rational = "rational",
+ inifinity = "infinity",
+ e = "expenonentiale",
+ i = "imaginaryi",
+ pi = "pi",
+ gamma = "gamma",
+ NaN = "NaN",
+ },
+ relation1 = {
+ eq = "eq",
+ lt = "lt",
+ gt = "gt",
+ neq = "neq",
+ leq = "leq",
+ geq = "geq",
+ approx = "approx",
+ },
+ set1 = {
+ cartesian_product = "cartesianproduct",
+ empty_set = "emptyset",
+ map = "map",
+ size = "card",
+ -- suchthat = "suchthat",
+ set = "set",
+ intersect = "intersect",
+ -- big_intersect = "",
+ union = "union",
+ -- big_union = "",
+ setdiff = "setdiff",
+ subset = "subset",
+ ["in"] = "in",
+ notin = "notin",
+ prsubset = "prsubset",
+ notsubset = "notsubset",
+ notprsubset = "notprsubset",
+ },
+ veccalc1 = {
+ divergence = "divergence",
+ grad = "grad",
+ curl = "curl",
+ laplacian = "laplacian",
+ Laplacian = "laplacian",
+ },
+ calculus1 = {
+ diff = "diff",
+ -- nthdiff = "",
+ partialdiff = "partialdiff",
+ int = "int",
+ -- defint = "defint",
+ },
+ integer1 = {
+ factorof = "factorof",
+ factorial = "factorial",
+ quotient = "quotient",
+ remainder = "rem",
+ },
+ linalg2 = {
+ vector = "vector",
+ matrix = "matrix",
+ matrixrow = "matrixrow",
+ },
+ mathmkeys = {
+ -- equiv = "",
+ -- contentequiv = "",
+ -- contentequiv_strict = "",
+ },
+ rounding1 = {
+ ceiling = "ceiling",
+ floor = "floor",
+ -- trunc = "trunc",
+ -- round = "round",
+ },
+ setname1 = {
+ P = "primes",
+ N = "naturalnumbers",
+ Z = "integers",
+ rationals = "rationals",
+ R = "reals",
+ complexes = "complexes",
+ },
+ complex1 = {
+ -- complex_cartesian = "complex_cartesian", -- ci ?
+ real = "real",
+ imaginary = "imaginary",
+ -- complex_polar = "complex_polar", -- ci ?
+ argument = "arg",
+ conjugate = "conjugate",
+ },
+ interval1 = { -- not an apply
+ -- integer_interval = "integer_interval",
+ interval = "interval",
+ interval_oo = { tag = "interval", closure = "open" },
+ interval_cc = { tag = "interval", closure = "closed" },
+ interval_oc = { tag = "interval", closure = "open-closed" },
+ interval_co = { tag = "interval", closure = "closed-open" },
+ },
+ linalg3 = {
+ -- vector = "vector.column",
+ -- matrixcolumn = "matrixcolumn",
+ -- matrix = "matrix.column",
+ },
+ minmax1 = {
+ min = "min",
+ -- big_min = "",
+ max = "max",
+ -- big_max = "",
+ },
+ piece1 = {
+ piecewise = "piecewise",
+ piece = "piece",
+ otherwise = "otherwise",
+ },
+ error1 = {
+ -- unhandled_symbol = "",
+ -- unexpected_symbol = "",
+ -- unsupported_CD = "",
+ },
+ limit1 = {
+ -- limit = "limit",
+ -- both_sides = "both_sides",
+ -- above = "above",
+ -- below = "below",
+ -- null = "null",
+ tendsto = "tendsto",
+ },
+ list1 = {
+ -- map = "",
+ -- suchthat = "",
+ -- list = "list",
+ },
+ multiset1 = {
+ size = { tag = "card", type = "multiset" },
+ cartesian_product = { tag = "cartesianproduct", type = "multiset" },
+ empty_set = { tag = "emptyset", type = "multiset" },
+ -- multi_set = { tag = "multiset", type = "multiset" },
+ intersect = { tag = "intersect", type = "multiset" },
+ -- big_intersect = "",
+ union = { tag = "union", type = "multiset" },
+ -- big_union = "",
+ setdiff = { tag = "setdiff", type = "multiset" },
+ subset = { tag = "subset", type = "multiset" },
+ ["in"] = { tag = "in", type = "multiset" },
+ notin = { tag = "notin", type = "multiset" },
+ prsubset = { tag = "prsubset", type = "multiset" },
+ notsubset = { tag = "notsubset", type = "multiset" },
+ notprsubset = { tag = "notprsubset", type = "multiset" },
+ },
+ quant1 = {
+ forall = "forall",
+ exists = "exists",
+ },
+ s_dist = {
+ -- mean = "mean.dist",
+ -- sdev = "sdev.dist",
+ -- variance = "variance.dist",
+ -- moment = "moment.dist",
+ },
+ s_data = {
+ mean = "mean",
+ sdev = "sdev",
+ variance = "vriance",
+ mode = "mode",
+ median = "median",
+ moment = "moment",
+ },
+ transc1 = {
+ log = "log",
+ ln = "ln",
+ exp = "exp",
+ sin = "sin",
+ cos = "cos",
+ tan = "tan",
+ sec = "sec",
+ csc = "csc",
+ cot = "cot",
+ sinh = "sinh",
+ cosh = "cosh",
+ tanh = "tanh",
+ sech = "sech",
+ csch = "cscs",
+ coth = "coth",
+ arcsin = "arcsin",
+ arccos = "arccos",
+ arctan = "arctan",
+ arcsec = "arcsec",
+ arcscs = "arccsc",
+ arccot = "arccot",
+ arcsinh = "arcsinh",
+ arccosh = "arccosh",
+ arctanh = "arstanh",
+ arcsech = "arcsech",
+ arccsch = "arccsch",
+ arccoth = "arccoth",
+ },
+}
+
+function xml.functions.remapmmlcsymbol(e)
+ local at = e.at
+ local cd = at.cd
+ if cd then
+ cd = csymbols[cd]
+ if cd then
+ local tx = e.dt[1]
+ if tx and tx ~= "" then
+ local tg = cd[tx]
+ if tg then
+ at.cd = nil
+ at.cdbase = nil
+ e.dt = { }
+ if type(tg) == "table" then
+ for k, v in next, tg do
+ if k == "tag" then
+ e.tg = v
+ else
+ at[k] = v
+ end
+ end
+ else
+ e.tg = tg
+ end
+ end
+ end
+ end
+ end
+end
+
+function xml.functions.remapmmlbind(e)
+ e.tg = "apply"
+end
+
+function xml.functions.remapopenmath(e)
+ local tg = e.tg
+ if tg == "OMOBJ" then
+ e.tg = "math"
+ elseif tg == "OMA" then
+ e.tg = "apply"
+ elseif tg == "OMB" then
+ e.tg = "apply"
+ elseif tg == "OMS" then
+ local at = e.at
+ e.tg = "csymbol"
+ e.dt = { at.name or "unknown" }
+ at.name = nil
+ elseif tg == "OMV" then
+ local at = e.at
+ e.tg = "ci"
+ e.dt = { at.name or "unknown" }
+ at.name = nil
+ elseif tg == "OMI" then
+ e.tg = "ci"
+ end
+ e.rn = "mml"
+end
+
+function mathml.checked_operator(str)
+ context(simpleoperatorremapper(str))
+end
+
+function mathml.stripped(str)
+ context(strip(str))
+end
+
+local p_entity = (P("&") * ((1-P(";"))^0) * P(";"))
+local p_utfchar = lpegpatterns.utf8character
+local p_spacing = lpegpatterns.whitespace^1
+
+local p_mn = Cs((p_entity/"" + p_spacing/utfchar(0x205F) + p_utfchar/n_replacements)^0)
+local p_strip = Cs((p_entity/"" + p_utfchar )^0)
+local p_mi = Cs((p_entity/"" + p_utfchar/i_replacements)^0)
+
+-- function mathml.mn(id,pattern)
+-- -- maybe at some point we need to interpret the number, but
+-- -- currently we assume an upright font
+-- local str = xmlcontent(getid(id)) or ""
+-- local rep = gsub(str,"&.-;","")
+-- local rep = gsub(rep,"(%s+)",utfchar(0x205F)) -- medspace e.g.: twenty one (nbsp is not seen)
+-- local rep = gsub(rep,".",n_replacements)
+-- ctx_mn(rep)
+-- end
+
+function mathml.mn(id,pattern)
+ -- maybe at some point we need to interpret the number, but
+ -- currently we assume an upright font
+ ctx_mn(lpegmatch(p_mn,xmlcontent(getid(id)) or ""))
+end
+
+-- function mathml.mo(id)
+-- local str = xmlcontent(getid(id)) or ""
+-- local rep = gsub(str,"&.-;","") -- todo
+-- context(simpleoperatorremapper(rep) or rep)
+-- end
+
+function mathml.mo(id)
+ local str = lpegmatch(p_strip,xmlcontent(getid(id)) or "")
+ context(simpleoperatorremapper(str) or str)
+end
+
+function mathml.mi(id)
+ -- we need to strip comments etc .. todo when reading in tree
+ local e = getid(id)
+ local str = e.dt
+ if type(str) == "table" then
+ local n = #str
+ if n == 0 then
+ -- nothing to do
+ elseif n == 1 then
+ local first = str[1]
+ if type(first) == "string" then
+ -- local str = gsub(first,"&.-;","") -- bah
+ -- local rep = i_replacements[str]
+ -- if not rep then
+ -- rep = gsub(str,".",i_replacements)
+ -- end
+ local str = lpegmatch(p_strip,first)
+ local rep = i_replacements[str] or lpegmatch(p_mi,str)
+ context(rep)
+ -- ctx_mi(rep)
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+ else
+ ctx_xmlflush(id) -- xmlsprint or so
+ end
+end
+
+function mathml.mfenced(id) -- multiple separators
+ id = getid(id)
+ local at = id.at
+ local left = at.open or "("
+ local right = at.close or ")"
+ local separators = at.separators or ","
+ local l = l_replacements[left]
+ local r = r_replacements[right]
+ ctx_enabledelimiter()
+ if l then
+ context(l_replacements[left] or o_replacements[left] or "")
+ else
+ context(o_replacements["@l"])
+ context(left)
+ end
+ ctx_disabledelimiter()
+ local collected = lxmlfilter(id,"/*") -- check the *
+ if collected then
+ local n = #collected
+ if n == 0 then
+ -- skip
+ elseif n == 1 then
+ xmlsprint(collected[1]) -- to be checked
+ else
+ local t = utfsplit(separators,true)
+ for i=1,n do
+ xmlsprint(collected[i]) -- to be checked
+ if i < n then
+ local m = t[i] or t[#t] or ""
+ if m == "|" then
+ m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter"
+ elseif m == doublebar then
+ m = "\\enabledelimiter\\middle|\\relax\\disabledelimiter"
+ elseif m == "{" then
+ m = "\\{"
+ elseif m == "}" then
+ m = "\\}"
+ end
+ context(m)
+ end
+ end
+ end
+ end
+ ctx_enabledelimiter()
+ if r then
+ context(r_replacements[right] or o_replacements[right] or "")
+ else
+ context(right)
+ context(o_replacements["@r"])
+ end
+ ctx_disabledelimiter()
+end
+
+local function flush(e,tag,toggle)
+ if tag == "none" then
+ -- if not toggle then
+ context("{}") -- {} starts a new ^_ set
+ -- end
+ elseif toggle then
+ context("^{")
+ xmlsprint(e.dt)
+ context("}{}") -- {} starts a new ^_ set
+ else
+ context("_{")
+ xmlsprint(e.dt)
+ context("}")
+ end
+ return not toggle
+end
+
+function mathml.mmultiscripts(id)
+ local done, toggle = false, false
+ for e in lxmlcollected(id,"/*") do
+ local tag = e.tg
+ if tag == "mprescripts" then
+ context("{}")
+ done = true
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ end
+ end
+ local done, toggle = false, false
+ for e in lxmlcollected(id,"/*") do
+ local tag = e.tg
+ if tag == "mprescripts" then
+ break
+ elseif done then
+ toggle = flush(e,tag,toggle)
+ else
+ xmlsprint(e)
+ done = true
+ end
+ end
+end
+
+local columnalignments = {
+ left = "flushleft",
+ right = "flushright",
+ center = "middle",
+}
+
+local rowalignments = {
+ top = "high",
+ bottom = "low",
+ center = "lohi",
+ baseline = "top",
+ axis = "lohi",
+}
+
+local frametypes = {
+ none = "off",
+ solid = "on",
+ dashed = "on",
+}
+
+-- crazy element ... should be a proper structure instead of such a mess
+
+function mathml.mcolumn(root)
+ root = getid(root)
+ local matrix, numbers = { }, 0
+ local function collect(m,e)
+ local tag = e.tg
+ if tag == "mi" or tag == "mn" or tag == "mo" or tag == "mtext" then
+ local str = xmltext(e)
+ str = lpegmatch(p_strip,str)
+ for s in utfcharacters(str) do
+ m[#m+1] = { tag, s }
+ end
+ if tag == "mn" then
+ local n = utflen(str)
+ if n > numbers then
+ numbers = n
+ end
+ end
+ elseif tag == "mspace" or tag == "mline" then
+ local str = e.at.spacing or ""
+ for s in utfcharacters(str) do
+ m[#m+1] = { tag, s }
+ end
+ -- elseif tag == "mline" then
+ -- m[#m+1] = { tag, e }
+ end
+ end
+ for e in lxmlcollected(root,"/*") do
+ local m = { }
+ matrix[#matrix+1] = m
+ if e.tg == "mrow" then
+ -- only one level
+ for e in lxmlcollected(e,"/*") do
+ collect(m,e)
+ end
+ else
+ collect(m,e)
+ end
+ end
+ ctx_halign()
+ ctx_bgroup()
+ context([[\hss\startimath\alignmark\stopimath\aligntab\startimath\alignmark\stopimath\cr]])
+ for i=1,#matrix do
+ local m = matrix[i]
+ local mline = true
+ for j=1,#m do
+ if m[j][1] ~= "mline" then
+ mline = false
+ break
+ end
+ end
+ if mline then
+ ctx_noalign([[\obeydepth\nointerlineskip]])
+ end
+ for j=1,#m do
+ local mm = m[j]
+ local tag, chr = mm[1], mm[2]
+ if tag == "mline" then
+ -- This code is under construction ... I need some real motivation
+ -- to deal with this kind of crap.
+--~ local n, p = true, true
+--~ for c=1,#matrix do
+--~ local mc = matrix[c][j]
+--~ if mc then
+--~ mc = mc[2]
+--~ if type(mc) ~= "string" then
+--~ n, p = false, false
+--~ break
+--~ elseif find(mc,"^[%d ]$") then -- rangecheck is faster
+--~ -- digit
+--~ elseif not find(mc,"^[%.%,]$") then -- rangecheck is faster
+--~ -- punctuation
+--~ else
+--~ n = false
+--~ break
+--~ end
+--~ end
+--~ end
+--~ if n then
+--~ chr = "\\mmlmcolumndigitrule"
+--~ elseif p then
+--~ chr = "\\mmlmcolumnpunctuationrule"
+--~ else
+--~ chr = "\\mmlmcolumnsymbolrule" -- should be widest char
+--~ end
+ chr = "\\hrulefill"
+ elseif tag == "mspace" then
+ chr = "\\mmlmcolumndigitspace" -- utfchar(0x2007)
+ end
+ if j == numbers + 1 then
+ context("\\aligntab")
+ end
+ local nchr = n_replacements[chr]
+ context(nchr or chr)
+ end
+ ctx_crcr()
+ end
+ ctx_egroup()
+end
+
+local spacesplitter = lpeg.tsplitat(" ")
+
+function mathml.mtable(root)
+ -- todo: align, rowspacing, columnspacing, rowlines, columnlines
+ root = getid(root)
+ local at = root.at
+ local rowalign = at.rowalign
+ local columnalign = at.columnalign
+ local frame = at.frame
+ local rowaligns = rowalign and lpegmatch(spacesplitter,rowalign)
+ local columnaligns = columnalign and lpegmatch(spacesplitter,columnalign)
+ local frames = frame and lpegmatch(spacesplitter,frame)
+ local framespacing = at.framespacing or "0pt"
+ local framespacing = at.framespacing or "-\\ruledlinewidth" -- make this an option
+
+ ctx_bTABLE { frame = frametypes[frame or "none"] or "off", offset = framespacing, background = "" } -- todo: use xtables and definextable
+ for e in lxmlcollected(root,"/(mml:mtr|mml:mlabeledtr)") do
+ ctx_bTR()
+ local at = e.at
+ local col = 0
+ local rfr = at.frame or (frames and frames [#frames])
+ local rra = at.rowalign or (rowaligns and rowaligns [#rowaligns])
+ local rca = at.columnalign or (columnaligns and columnaligns[#columnaligns])
+ local ignorelabel = e.tg == "mlabeledtr"
+ for e in lxmlcollected(e,"/mml:mtd") do -- nested we can use xml.collected
+ col = col + 1
+ if ignorelabel and col == 1 then
+ -- get rid of label, should happen at the document level
+ else
+ local at = e.at
+ local rowspan = at.rowspan or 1
+ local columnspan = at.columnspan or 1
+ local cra = rowalignments [at.rowalign or (rowaligns and rowaligns [col]) or rra or "center"] or "lohi"
+ local cca = columnalignments[at.columnalign or (columnaligns and columnaligns[col]) or rca or "center"] or "middle"
+ local cfr = frametypes [at.frame or (frames and frames [col]) or rfr or "none" ] or "off"
+ ctx_bTD { align = formatters["{%s,%s}"](cra,cca), frame = cfr, nx = columnspan, ny = rowspan }
+ if xmlempty(e,".") then
+ -- nothing, else hsize max
+ else
+ ctx_startimath()
+ -- ctx_ignorespaces()
+ xmlcprint(e)
+ -- ctx_removeunwantedspaces()
+ ctx_stopimath()
+ end
+ ctx_eTD()
+ end
+ end
+ -- if e.tg == "mlabeledtr" then
+ -- ctx_bTD()
+ -- xmlcprint(xml.first(e,"/!mml:mtd"))
+ -- ctx_eTD()
+ -- end
+ ctx_eTR()
+ end
+ ctx_eTABLE()
+end
+
+function mathml.csymbol(root)
+ root = getid(root)
+ local at = root.at
+ local encoding = at.encoding or ""
+ local hash = url.hashed(lower(at.definitionUrl or ""))
+ local full = hash.original or ""
+ local base = hash.path or ""
+ local text = strip(xmltext(root) or "")
+ ctx_mmlapplycsymbol(full,base,encoding,text)
+end
+
+local p = lpeg.Cs(((1-lpegpatterns.whitespace)^1 / "mml:enclose:%0" + (lpegpatterns.whitespace^1)/",")^1)
+
+function mathml.menclosepattern(root)
+ root = getid(root)
+ local a = root.at.notation
+ if a and a ~= "" then
+ context(lpegmatch(p,a))
+ end
+end
+
+function xml.is_element(e,name)
+ return type(e) == "table" and (not name or e.tg == name)
+end
+
+function mathml.cpolar_a(root)
+ root = getid(root)
+ local dt = root.dt
+ ctx_mathopnolimits("Polar")
+ ctx_left(false,"(")
+ for k=1,#dt do
+ local dk = dt[k]
+ if xml.is_element(dk,"sep") then
+ context(",")
+ else
+ xmlsprint(dk)
+ end
+ end
+ ctx_right(false,")")
+end
+
+-- crap .. maybe in char-def a mathml overload
+
+local mathmleq = {
+ [utfchar(0x00AF)] = utfchar(0x203E),
+}
+
+function mathml.extensible(chr)
+ context(mathmleq[chr] or chr)
+end
diff --git a/tex/context/modules/mkiv/x-mathml.mkiv b/tex/context/modules/mkiv/x-mathml.mkiv
new file mode 100644
index 000000000..ec56aa3df
--- /dev/null
+++ b/tex/context/modules/mkiv/x-mathml.mkiv
@@ -0,0 +1,2605 @@
+%D \module
+%D [ file=x-mathml,
+%D version=2008.05.29,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\MATHML,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% \xmlfilter{#1}{/*/name()} -> \xmltag
+
+% This module is under construction and will be cleaned up. We use a funny mix of
+% xml, tex and lua. I could rewrite the lot but it also shows how context evolves.
+%
+% I might end up with a lua-only implementation some day. I must find a good reason
+% to spend time on it. In fact, it might even be more messy.
+%
+% no m:text strip (needs checking, maybe nbsp is mandate
+%
+% todo: more will be moved to lua (less hassle)
+% todo: move left/right to the lua end
+%
+% this implememation looks like a hack ... this is because we deal with all weird cases we
+% ran into, including abuse that was supposed to render ok (even if it didn't in other
+% renderers) .. it was simply expected to work that way.
+
+\writestatus{loading}{ConTeXt XML Macros / MathML Renderer}
+
+\unprotect
+
+\usemodule[x][calcmath]
+%usemodule[x][asciimath]
+
+\startmodule [mathml]
+
+\registerctxluafile{x-mathml}{}
+
+\def\ctxmodulemathml#1{\ctxlua{moduledata.mathml.#1}}
+
+\startxmlsetups xml:mml:define
+ \xmlsetsetup{#1} {(formula|subformula)} {mml:formula}
+ \xmlfilter {#1} {omt:*/function(remapopenmath)}
+ \xmlfilter {#1} {mml:bind/function(remapmmlbind)}
+ \xmlfilter {#1} {mml:csymbol/function(remapmmlcsymbol)}
+ \xmlsetsetup{#1} {mml:*} {mml:*}
+ \xmlsetsetup{#1} {mml:apply/mml:apply/mml:inverse/../..} {mml:apply:inverse}
+ \xmlstrip {#1} {(mml:mi|mml:mo|mml:mn|mml:csymbol)}
+\stopxmlsetups
+
+\xmlregisterns{omt}{openmath}
+\xmlregisterns{mml}{mathml}
+
+\xmlregistersetup{xml:mml:define}
+
+% \unexpanded\def\MMLhack % no longer needed
+% {\let\MMLpar\par
+% \let\par\relax
+% \everyvbox{\let\par\MMLpar}}
+
+\xmlmapvalue {mml:math:mode} {display} {\displaymathematics} % we had this already
+\xmlmapvalue {mml:math:mode} {inline} {\inlinemathematics }
+
+\xmlmapvalue {mml:math:display} {block} {\displaymathematics} % before this showed up
+\xmlmapvalue {mml:math:display} {inline} {\inlinemathematics }
+
+\xmlmapvalue {mml:math:dir} {ltr} {\setfalse\c_math_right_to_left\math_basics_synchronize_direction}
+\xmlmapvalue {mml:math:dir} {rtl} {\settrue \c_math_right_to_left\math_basics_synchronize_direction}
+
+\startxmlsetups mml:math
+ \begingroup
+ \enableautofences
+ \xmlval {mml:math:dir} {\xmlatt{#1}{dir}} {}
+ \xmlval {mml:math:display} {\xmlatt{#1}{display}} {
+ \xmlval {mml:math:mode} {\xmlatt{#1}{mode}} {
+ \automathematics
+ }
+ }
+ {
+ %\math_fences_checked_start
+ %\MMLhack
+ \xmlflush{#1}
+ %\math_fences_checked_stop
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:imath
+ \inlinemathematics {
+ \enableautofences
+ %\math_fences_checked_start
+ %\MMLhack
+ \xmlflush{#1}
+ %\math_fences_checked_stop
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:dmath
+ \displaymathematics {
+ \enableautofences
+ %\math_fences_checked_start
+ %\MMLhack
+ \xmlflush{#1}
+ %\math_fences_checked_stop
+ }
+\stopxmlsetups
+
+%D First we define some general formula elements.
+
+\startxmlsetups mml:formula
+ \edef\mmlformulalabel {\xmlatt{#1}{label}\xmlatt{#1}{id}}
+ \edef\mmlformulasublabel{\xmlatt{#1}{sublabel}\xmlatt{#1}{id}}
+ \doifsomething\mmlformulalabel{\placeformula[\mmlformulalabel]{\mmlformulasublabel}}
+ \startformula
+ %\MMLhack
+ \xmlfirst{#1}{/mml:math}
+ \stopformula
+\stopxmlsetups
+
+% old delimiter hacks
+%
+% \setfalse\mmlignoredelimiter
+% \settrue \mmlsomeleftdelimiter
+%
+% \def\MMLleftorright
+% {\ifconditional\mmlsomeleftdelimiter
+% \setfalse\mmlsomeleftdelimiter\expandafter\MMLleft
+% \else
+% \settrue \mmlsomeleftdelimiter\expandafter\MMLright
+% \fi}
+%
+% \ifx\MMLleft \undefined \let\MMLleft \firstofoneargument \fi
+% \ifx\MMLright \undefined \let\MMLright \firstofoneargument \fi
+% \ifx\MMLmiddle\undefined \let\MMLmiddle\firstofoneargument \fi
+%
+% \def\mmlleftdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLleft #1}\fi}
+% \def\mmlrightdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLright #1}\fi}
+% \def\mmlmiddledelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLmiddle #1}\fi}
+% \def\mmlleftorrightdelimiter#1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{\MMLleftorright#1}\fi}
+
+% new delimiter hacks (assumes wrapping)
+%
+% \math_fences_checked_start
+% \math_fences_checked_stop
+%
+% \math_fences_checked_left
+% \math_fences_checked_middle
+% \math_fences_checked_right
+% \math_fences_checked_left_or_right
+
+\setfalse\mmlignoredelimiter % alternatively we could turn it on/off inside the start/stop and ignore \left\right\middle otherwise
+
+% \def\mmlleftdelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_left \fi}
+% \def\mmlrightdelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_right \fi}
+% \def\mmlmiddledelimiter {\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_middle \fi}
+% \def\mmlleftorrightdelimiter{\ifconditional\mmlignoredelimiter\else\expandafter\math_fences_checked_left_or_right\fi}
+
+\let\mmlleftdelimiter \autofenceopen
+\let\mmlmiddledelimiter \autofencemiddle
+\let\mmlrightdelimiter \autofenceclose
+\let\mmlleftorrightdelimiter\autofenceboth
+
+% end of delimiter mess
+
+\def\mmlchar#1{\char#1 } % used in lua code
+
+% \newcount\delimiternesting \appendtoks \delimiternesting\zerocount \to \everymathematics
+
+% \def\mmlleftdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{%
+% \advance\delimiternesting\plusone \MMLleft #1}\fi}
+% \def\mmlrightdelimiter #1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{%
+% \advance\delimiternesting\plusone \MMLright#1}\fi}
+% \def\mmlmiddledelimiter#1{\ifconditional\mmlignoredelimiter#1\else\normalordelimiter{#1}{%
+% \ifcase\delimiternesting\MMLleft\else\MMLmiddle\fi#1}\fi}
+
+%D Remark: from now on this is a module and no longer an xtag
+%D filter. There is an intermediate cleaner module but it has
+%D some namespace limitations. Here we do it the \MKIV\ way.
+
+%D The rendering macros:
+
+\def\MMLrm{\mr}
+
+\def\MMLseparator#1{\removeunwantedspaces{#1}\ignorespaces} % nils space after separator
+\def\MMLseparator#1{,} % todo, for europe we need to block the space
+
+%D Since I only had the draft of MathML 2 and later 3 as example of
+%D rendering, there are probably a lot of omissions and
+%D misinterpretations. At least I learned some bits and
+%D pieces of math rendering.
+%D
+%D The main complications were not so much the math, but to
+%D find the most efficient way to handle elements without
+%D spacing beging messed up. The first implementation was
+%D aimed at getting reasonable output, this second
+%D implementation is already better in terms of handling
+%D nesting, and I will definitely need a third one that has
+%D more efficient and less ugly code.
+%D
+%D The \TEX\ part is not that complicated and once the
+%D preprocessor was okay, the rest way just a lot of keying
+%D and testing. It all comes down to gobbling, redefining,
+%D and not so much to parsing.
+%D
+%D The second implementation expanded the whole math sequence
+%D into an internal \TEX\ representation. This is a rather clean
+%D and fast process. Filtering and testing takes place by
+%D redefining teh internal representation macros.
+%D
+%D The third implementation may look a bit more messy in some
+%D respects. This is because in \TEX\ it's not that trivial to
+%D implement a tree handler. We use a stack for the \type {apply}
+%D element and other sequential content. Occasionally we need to
+%D peek into child elements which involves messy code. This
+%D implementation is closer to the normal \XML\ handling in
+%D \CONTEXT.
+
+%D We start with the parent elements and the option handler.
+
+\unexpanded\def\xmlmathmldirective#1{\dosetvalue{MML#1}}
+
+\xmlinstalldirective{mathml}{xmlmathmldirective}
+
+%def\xmlmathmldirective#1#2#3{[#1][#2][#3]\dosetvalue{MML#1}{#2}{#3}}
+
+%D In the styles, options can be set with:
+
+\unexpanded\def\setupMMLappearance[#1]{\dodoubleargument\getparameters[MML#1]} % no @@ because passed to lua
+
+%D We will apply inner math to all bits and pieces made up by an
+%D \type {apply}.
+
+\def\MMLmathinner
+ {\ifinner
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\mathinner
+ \fi}
+
+%D Auxiliary MathML macros: (to be generalized)
+
+\def\mmlfirst #1{\xmlelement{#1}{1}} % we can move these inline if needed
+\def\mmlsecond #1{\xmlelement{#1}{2}}
+\def\mmlthird #1{\xmlelement{#1}{3}}
+\def\mmlprelast#1{\xmlelement{#1}{-2}}
+\def\mmllast #1{\xmlelement{#1}{-1}}
+
+\unexpanded\def\mmlunexpandedfirst #1{\xmlelement{#1}{1}} % we can move these inline if needed
+\unexpanded\def\mmlunexpandedsecond #1{\xmlelement{#1}{2}}
+\unexpanded\def\mmlunexpandedthird #1{\xmlelement{#1}{3}}
+
+\starttexdefinition doifelsemmlfunction #1
+ \xmldoifelse {#1} {/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:apply/mml:fn} {
+ \firstoftwoarguments
+ } {
+ \xmldoifelse {#1} {/mml:ci[@type=='fn']} {
+ \firstoftwoarguments
+ } {
+ \secondoftwoarguments
+ }
+ }
+ }
+\stoptexdefinition
+
+%D A couple of lists:
+
+\convertargument
+ mml:times|mml:divide|mml:power|%
+ mml:lt|mml:gt|mml:eq|mml:leq|mml:geq|%
+ mml:in|mml:inverse|%
+ mml:fn|%
+ mml:floor|mml:ceiling|%
+ mml:mean|%
+ mml:selector|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:outerproduct|mml:innerproduct|mml:scalarproduct%
+\to \MMLcmainresetlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs|mml:int|mml:limit|mml:sum|mml:product|%
+ mml:fn%
+\to \MMLcfunctionlist
+
+\convertargument
+ mml:sin|mml:arcsin|mml:sinh|mml:arcsinh|%
+ mml:cos|mml:arccos|mml:cosh|mml:arccosh|%
+ mml:tan|mml:arctan|mml:tanh|mml:arctanh|%
+ mml:cot|mml:arccot|mml:coth|mml:arccoth|%
+ mml:csc|mml:arccsc|mml:csch|mml:arccsch|%
+ mml:sec|mml:arcsec|mml:sech|mml:arcsech|%
+ mml:ln|mml:exp|mml:log|%
+ mml:abs%
+\to \MMLcpurefunctionlist
+
+\convertargument
+ mml:diff|mml:partialdiff|mml:root%
+\to \MMLcconstructlist
+
+%D We use inner and grouping (begin/end and no b/e) else we
+%D get problems with 1/2(1+2) and alike (todo: ask taco).
+%D
+%D The problem with apply is that we need to take care of
+%D several situations, like:
+%D
+%D \starttyping
+%D <apply> <.../> ...
+%D <apply> <fn> ...
+%D <apply> <apply> <ci> ...
+%D <apply> <apply> <fn> <ci> ...
+%D \stoptyping
+%D
+%D Because we translated version 2 of this renderer into
+%D version 3 the following definitions may be sub optimal or
+%D more complex than actually needed.
+
+%D We will more more to lua ...
+
+% simple version
+
+\newcount\@MMLlevel \def\MMLcreset{\@MMLlevel\zerocount}
+
+\let\MMLctempresetlist\empty \def\setMMLcreset{\edef\MMLctempresetlist}
+
+\let\MMLdoL\donothing
+\let\MMLdoR\donothing
+
+\newcount\mmlapplydepth \def\MMLcreset{\mmlapplydepth\zerocount}
+
+% \newtoks \@@postponedMMLactions \setfalse \somepostponedMMLactions
+%
+% \def\postponeMMLactions#1%
+% {\global\settrue\somepostponedMMLactions
+% \global\@@postponedMMLactions\expandafter{\the\@@postponedMMLactions#1}}
+%
+% \def\postponedMMLactions
+% {\global\setfalse\somepostponedMMLactions
+% \@EA\global\@EA\@@postponedMMLactions\@EA\emptytoks
+% \the\@@postponedMMLactions}
+
+\startxmlsetups mml:apply
+ \MMLmathinner {
+ \xmldoif {#1} {/(\MMLcmainresetlist\string|\MMLctempresetlist)} {
+ % \MMLcreset
+ }
+ \edef\mmlapplyopentoken {\xmlatt{#1}{open}}
+ \edef\mmlapplyclosetoken{\xmlatt{#1}{close}}
+ \ifcase\mmlapplydepth \else
+ \ifx\mmlapplyopentoken\empty
+ \def\mmlapplyopentoken {(}
+ \def\mmlapplyclosetoken{)}
+ \fi
+ \fi
+ \advance\mmlapplydepth\plusone
+ \begingroup
+ \ifx\mmlapplyopentoken\empty
+ \let\MMLdoL\donothing
+ \let\MMLdoR\donothing
+ \else
+ \edef\MMLdoL{\noexpand\left \mmlapplyopentoken }
+ \edef\MMLdoR{\noexpand\right\mmlapplyclosetoken}
+ \fi
+ \let\MMLctempresetlist\empty
+ \xmldoifelse {#1} {/mml:apply} {
+% % <apply> <apply> ... </apply> <ci> .. </ci> </apply>
+% \xmldoifelse {#1} {/mml:apply(mml:plus|mml:minus)} {% [a]
+% % yet incomplete and rather untested
+% % <apply> <apply> <minus/> <tan/> <cos/> </apply> <ci>x</ci> </apply>
+ } {% [b]
+% \MMLcreset
+ }
+% \MMLdoL
+% \mmlfirst{#1}
+% \ifconditional\somepostponedMMLactions
+% \postponedMMLactions
+% \else
+% \left(\MMLcreset\mmlsecond{#1}\right)
+% \fi
+% \MMLdoR
+% } {
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}}
+ \doifelsesetups {mml:apply:mml:\mmlapplyaction} {
+ \xmlsetup{#1}{mml:apply:mml:\mmlapplyaction}
+ } {
+% \MMLdoL
+ \xmlsetup{#1}{mml:\xmlfilter{#1}{/*/name()}}
+% \MMLdoR
+ }
+% }
+ \endgroup
+ \advance\mmlapplydepth\minusone
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:apply
+ \xmlflush{#1}
+ \xmlall{#1}{../[position()>1]}
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:fn
+ \xmldoifelse {#1} {/mml:fn/mml:ci} {
+ \edef\mmlfnci{\xmlstripped{#1}{/mml:fn/mml:ci}}% was xmlcontent
+ \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:...
+ \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin
+ } {
+ \MMLcreset
+ \MMLdoL
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \negthinspace % not enough
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+ \MMLdoR
+ }
+ } {
+ \MMLcreset
+ \MMLdoL
+ \xmlall{#1}{/*}
+ \MMLdoR
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:csymbol
+ \xmlsetup{#1}{mml:csymbol}% \MMLdoL/MMLdoR to be handled in plugin
+\stopxmlsetups
+
+\startxmlsetups mml:apply:mml:ci
+ \xmlfirst{#1}{/mml:ci}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \left(\MMLcreset\xmlconcatrange{#1}{/*}{2}{}{\MMLseparator,}\right)
+ \fi
+\stopxmlsetups
+
+% reln
+
+\startxmlsetups mml:reln
+ \writestatus{XML}{MathML element "reln" is obsolete}
+\stopxmlsetups
+
+% fn
+
+% plusminus ±
+
+\startxmlsetups mmc:fn:\utfchar{"00B1}
+ \MMLdoL
+ \xmlconcat{#1}{/[position()>1]}{\utfchar{"00B1}}
+ \MMLdoR
+\stopxmlsetups
+
+% minusplus
+
+\startxmlsetups mmc:fn:\utfchar{"2213}
+ \MMLdoL
+ \xmlconcat{#1}{/[position()>1]}{\utfchar{"2213}}
+ \MMLdoR
+\stopxmlsetups
+
+\startxmlsetups mmc:fn
+ \begingroup
+ \edef\mmlnoffn{\xmlcount{#1}{/*}}
+ \ifnum\mmlnoffn>\plustwo
+ \def\MMCfnleft {\left(}
+ \def\MMCfnright{\right)}
+ \else
+ \let\MMCfnleft \relax
+ \let\MMCfnright\relax
+ \fi
+ \xmldoifelse {#1} {/mml:ci} { % first
+ \edef\mmlfnci{\xmltext{#1}{/mml:ci}}% was xmlcontent
+ \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:...
+ \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin
+ } {
+ \MMLcreset
+ \mmlfirst{#1}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:apply} { % first
+ \xmldoifelse {#1} {/(mml:plus\string|mml:minus)} {
+ \left(\mmlfirst{#1}\right)
+ } {
+ \mmlfirst{#1}
+ }
+ \ifnum\mmlnoffn>\plusone
+ \left(\xmlall{#1}{/!mml:apply}\right)
+ \fi
+ } {
+ \MMLcreset
+ \negthinspace
+ \MMCfnleft
+ \ifnum\mmlnoffn=\plustwo,\fi
+ \xmlconcat{#1}{/*}{2}{}{\MMLseparator,}
+ \MMCfnright
+ }
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mmc:fn:apply % where used?
+ \xmldoifelse {#1} {/mml:ci} { % first
+ \edef\mmlfnci{\xmltext{#1}{/mml:ci}}% was xmlcontent
+ \doifelsesetups{mmc:fn:\mmlfnci} { % was mmc:fn:...
+ \xmlsetup{#1}{mmc:fn:\mmlfnci} % \MMLdoL/MMLdoR to be handled in plugin
+ } {
+ \MMLcreset
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \negthinspace
+ \left(\MMLcreset\xmlconcat{#1}{2}{}{\MMLseparator,}\right)
+ \fi
+ }
+ } {
+ \endgroup
+ \MMLcreset
+ \mmlfirst{#1}
+ }
+\stopxmlsetups
+
+%D The next definition provide a kind of plug-in mechanism (see
+%D the open math extension module).
+
+% http://www.publishers.com/somename
+%
+% called at the lua end
+
+\starttexdefinition mmlapplycsymbol #1#2#3#4
+ % #1=full url, #2=name, #3=encoding, #4=text
+ \doifelse {#3} {text} {
+ \text{#4}
+ } {
+ \doifelsesetups {mml:csymbol:#1} {
+ % full url
+ \fastsetup{mml:csymbol:#1}
+ } {
+ % somename (fallback)
+ \doifelsesetups {mml:csymbol:#2} {
+ \fastsetup{mml:csymbol:#2}
+ } {
+ \xmlval{mmc:cs}{#3}{}% todo
+ }
+ }
+ }
+\stoptexdefinition
+
+\startxmlsetups mml:csymbol
+ \ctxmodulemathml{csymbol("#1")}
+\stopxmlsetups
+
+\startxmlsetups mml:csymbol:cdots
+ \cdots
+\stopxmlsetups
+
+% \startxmlsetups mml:csymbol:<url> \stopxmlsetups
+
+%D Alternative b will convert periods into comma's:
+
+\setupMMLappearance[cn] [\c!alternative=\v!a]
+\setupMMLappearance[polar] [\c!alternative=\v!a] % a|b|c
+\setupMMLappearance[float] [\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[enotation][\c!symbol=\v!no] % \v!yes|dot
+\setupMMLappearance[base] [\c!symbol=\v!numbers] % digits|characters|text|no
+
+\startxmlsetups mml:cs \xmlcommand{#1}{/}{mml:cs:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:ci \xmlcommand{#1}{/}{mml:ci:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+\startxmlsetups mml:cn \xmlcommand{#1}{/}{mml:cn:\xmlattdef{#1}{type}{default}} \stopxmlsetups
+
+% helpers cn / todo: \mn{...}
+
+\startxmlsetups mml:cn:default
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+% helpers ci
+
+\startxmlsetups mml:ci:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:set
+ {\blackboard{\xmlflush{#1}}} % todo
+\stopxmlsetups
+
+\startxmlsetups mml:ci:vector
+ \overrightarrow{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:matrix
+ {\bi\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:function
+ \xmlflush{#1}% \negthinspace
+\stopxmlsetups
+
+\startxmlsetups mml:ci:fn
+ \xmlsetup{#1}{mml:ci:function}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:ci:polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+% helpers ci
+
+\startxmlsetups mml:cn:default
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:integer
+ \edef\mmlintegerbase{\xmlattdef{#1}{base}{}}
+ \ifx\mmlintegerbase\empty
+ \xmlflush{#1}
+ \else
+ \doifelse \MMLbasesymbol \v!no {
+ \MMLcCNbasedata{\xmlflush{#1}}
+ } {
+ \MMLcCNbasedata{\xmlflush{#1}}\normalsubscript{
+ \hbox {\startimath
+ \mr
+ \scriptscriptstyle
+ \processaction
+ [\MMLbasesymbol]
+ [\v!characters=>\MMLcCNbasestring BODH,
+ \v!text=>\MMLcCNbasestring{BIN}{OCT}{DEC}{HEX},
+ \s!unknown=>\mmlintegerbase]
+ \stopimath}
+ }
+ }
+ \fi
+\stopxmlsetups
+
+\def\MMLcCNbasedata#1%
+ {\ifnum\mmlintegerbase>10 \relax{\mr#1}\else#1\fi}
+
+\def\MMLcCNbasestring#1#2#3#4%
+ {\ifnum\mmlintegerbase= 2 #1\else
+ \ifnum\mmlintegerbase= 8 #2\else
+ \ifnum\mmlintegerbase=10 #3\else
+ \ifnum\mmlintegerbase=16 #4\else
+ \mmlintegerbase \fi\fi\fi\fi}
+
+\startxmlsetups mml:cn:polar
+ \xmlsetup{#1}{mml:cn:polar:\MMLpolaralternative}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:a
+ \ctxmodulemathml{cpolar_a("#1")}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:b
+ {\mr e}\normalsuperscript{\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:polar:c
+ \exp\left(\xmlsnippet{#1}{1}+\xmlsnippet{#1}{3}\thinspace{\mr i}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-polar
+ \xmlsetup{#1}{mml:cn:polar}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex % todo ( )
+ \left(\xmlsnippet{#1}{1} + \xmlsnippet{#1}{3}\thinspace{\mr i}\right)
+\stopxmlsetups
+
+\startxmlsetups mml:cn:complex-cartesian
+ \xmlsetup{#1}{mml:cn:complex}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:float
+ \doifelse \MMLfloatsymbol \v!no {
+ % make sure that e shows up ok
+ \mathopnolimits{\xmlflush{#1}}
+ } {
+ % we should ignore \entities !
+ \edef\mmlfloatstring{\xmlflush{#1}}
+ \splitstring\mmlfloatstring\at e\to\first\and\last
+ \ifx\first\empty
+ \mmlfloatstring
+ \else\ifx\last\empty
+ \mmlfloatstring
+ \else
+ \first
+ \doifelse \MMLfloatsymbol {dot} \cdot \times
+ 10\normalsuperscript{\last}
+ \fi \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:real
+ \xmlsetup{#1}{mml:cn:float}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:e-notation
+ \doifelse \MMLenotationsymbol \v!no {
+ \xmlsnippet{#1}{1}
+ \unskip\mathopnolimits{e}\ignorespaces
+ \xmlsnippet{#1}{3}
+ } {
+ \xmlsnippet{#1}{1}
+ \doifelse \MMLenotationsymbol {dot} \cdot
+ \times10\normalsuperscript{\xmlsnippet{#1}{3}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:cn:logical
+ \mathopnolimits{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:cn:rational
+ \xmldoifelse {#1} {/mml:sep} {
+ \mmlfrac
+ {\xmlsnippet{#1}{1}}
+ {\xmlsnippet{#1}{3}}
+ } {
+ \xmlflush{#1}
+ }
+\stopxmlsetups
+
+% interval
+
+\setupMMLappearance[interval][\c!alternative=\v!a,\c!separator={,}]
+
+% when empty element, then it's an apply
+
+\startxmlsetups mml:interval
+ \doifelse {\xmltag{#1}} {apply} {
+ % #1 == apply
+ \let\mmlintervalfirst \mmlsecond
+ \let\mmlintervalsecond\mmlthird
+ \xmlsetup{#1}{mml:interval:\xmlattributedef{#1}{/mml:interval}{closure}{closed}}
+ } {
+ % #1 == interval
+ \let\mmlintervalfirst \mmlfirst
+ \let\mmlintervalsecond\mmlsecond
+ \xmlsetup{#1}{mml:interval:\xmlattdef{#1}{closure}{closed}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open-closed
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+ } {
+ \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right]
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:closed-open
+ \doifelse \MMLintervalalternative \v!b {
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
+ } {
+ \left[\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:interval:open
+ \doifelse \MMLintervalalternative \v!b {
+ \left<\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right>
+ } {
+ \left(\mmlintervalfirst{#1}\MMLseparator\MMLintervalseparator\mmlintervalsecond{#1}\right)
+ }
+\stopxmlsetups
+
+% inverse
+
+\setfalse\xmlinversefunction
+
+\startxmlsetups mml:apply:inverse
+ \settrue\xmlinversefunction
+ \xmlsetup{#1}{mml:\xmlfilter{#1}{/mml:apply/*[2]/name()}}
+\stopxmlsetups
+
+% condition
+
+% maybe a fast \xmlnonfirst
+
+% instead of the following we could do \xmlcontent{#1}{/mml:bvar} etc
+
+\startxmlsetups mml:bvar \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:lowlimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:uplimit \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:degree \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:logbase \xmlflush{#1} \stopxmlsetups
+\startxmlsetups mml:fn \xmlflush{#1} \stopxmlsetups
+
+\startxmlsetups mml:condition
+% \xmldoif {#1} {/mml:bvar} {
+% \xmlfirst{#1}{/mml:bvar}\mid
+% }
+ \xmlall{#1}{/!(mml:condition\string|mml:bvar)}
+\stopxmlsetups
+
+% declare
+
+\setupMMLappearance[declare][\c!state=\v!start]
+
+\startxmlsetups mml:declare
+ \doif \MMLdeclarestate \v!start {
+ \mathopnolimits{declare}
+ \mmlfirst{#1}
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \thickspace
+ \mathopnolimits{as}
+ \thickspace
+ \fi
+ \mmlsecond{#1}
+ }
+\stopxmlsetups
+
+% lambda
+
+\setupMMLappearance[lambda][\c!alternative=b]
+
+\startxmlsetups mml:lambda
+ \begingroup
+ \doifelse \MMLlambdaalternative \v!a {
+ \lambda\left(\xmlconcat{#1}{/!mml:lambda}{\MMLseparator,}\right)
+ } {
+ \ifnum\xmlcount{#1}{/mml:bvar}>\plusone
+ \left(\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}\right)
+ \else
+ \xmlfirst{#1}{/mml:bvar}
+ \fi
+ \mapsto
+ \MMLcreset
+ \xmlall{#1}{/!(mml:bvar|mml:lambda)}
+ }
+ \endgroup
+\stopxmlsetups
+
+% compose
+
+\startxmlsetups mml:compose
+ \begingroup
+ \MMLcreset
+% \let\MMLcCIfunction\firstofoneargument % brrr ? ? ?
+ \doifelsemmlfunction {#1} {
+ \left(\xmlconcat{#1}{/!mml:compose}{\circ}\right)
+ } {
+ \xmlconcat{#1}{/!mml:compose}{\circ}
+ }
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:image
+ \mathopnolimits{image} \left( {\mr\xmlfilter{#1}{/!mml:image/tag()}} \right)
+\stopxmlsetups
+
+\setupMMLappearance[piece][\c!separator=]
+
+\startxmlsetups mml:piecewise
+ \processaction
+ [\MMLpieceseparator]
+ [ \v!yes=>\def\theMMLpieceseparator{,&},
+ \v!no=>\def\theMMLpieceseparator{&},
+ \s!default=>\def\theMMLpieceseparator{&},
+ \s!unknown=>\def\theMMLpieceseparator{\,\,\hbox{\MMLpieceseparator}\,\,}]
+ \cases{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:piece
+ \mmlfirst{#1}\theMMLpieceseparator\mathematics{\mmlsecond{#1}}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:otherwise
+% \xmlflush{#1}\MMLcPIECEseparator&{\mr otherwise}\crcr
+ \xmlflush{#1}&{\mr otherwise}\crcr
+\stopxmlsetups
+
+% end of piece
+
+\startxmlsetups mml:quotient
+ \lfloor\mmlsecond{#1}/\mmlthird{#1}\rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:factorial
+ \xmlall{#1}{/!factorial}!
+\stopxmlsetups
+
+\setupMMLappearance [divide] [\c!level=\!!maxcard,\c!alternative=\v!a]
+
+\newcount\mmldividelevel
+
+\startxmlsetups mml:divide
+ \advance\mmldividelevel\plusone
+ \doifelse \MMLdividealternative \v!b {
+ \mmlsecond{#1}/\mmlthird{#1}
+ } {
+ \ifnum \mmldividelevel > \MMLdividelevel \relax % threshold
+ \mmlsecond{#1}/\mmlthird{#1}
+ \else
+ \MMLcreset
+ \mmlfrac{\MMLcreset\mmlsecond{#1}}{\MMLcreset\mmlthird{#1}}
+ \fi
+ }
+ \advance\mmldividelevel\minusone
+\stopxmlsetups
+
+% min max
+
+\startxmlsetups mml:min \mathopnolimits{min} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+\startxmlsetups mml:max \mathopnolimits{max} \xmlsetup{#1}{mml:minmax} \stopxmlsetups
+
+\startxmlsetups mml:minmax
+ \xmldoif {#1} {/mml:bvar} {
+ {}\normalsubscript{\xmlfirst{#1}{/mml:bvar}}
+ }
+ \left\{
+ \xmlconcat{#1}{/!(mml:bvar\string|mml:max\string|mml:min)}{\MMLseparator,}
+ \right\}
+\stopxmlsetups
+
+% minus plus
+
+\setupMMLappearance [plus] [\c!alternative=\v!a] % b = no sign -> 3 1/4
+\setupMMLappearance [sign] [\c!reduction=\v!yes]
+
+% alternative b -> geen sign
+
+% branch needed, else (a-b) + (c-d) goes wrong
+% reset check in case of (-x) + 37
+% reset check in case of (-x) + 37
+
+\newcount\mmlpluscounter
+
+\startxmlsetups mml:plus
+ \doifelse \MMLsignreduction \v!yes {
+ \MMLdoL
+ \xmlsetup{#1}{mml:plus:reset}
+ \xmlcommand{#1}{/!mml:plus}{mml:plus:body}
+ \MMLdoR
+ } {
+ \ifnum\xmlcount{#1}{/!mml:plus}=\plusone
+ +\xmlfirst{#1}{/!mml:plus}
+ \else
+ \MMLdoL
+ \xmlconcat{#1}{/!mml:plus}{+}
+ \MMLdoR
+ \fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:plus:reset
+ \mmlpluscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:plus:body
+ \advance\mmlpluscounter\plusone
+ \ifnum\mmlpluscounter>\plusone
+ \xmldoifelse{#1}{/mml:minus} {
+ \ifnum\xmlcount{#1}{/!mml:minus}>\plusone
+ +
+ \fi
+ } {
+ \doifelse {\xmlatt{#1}{type}} {rational} {
+ % fraction
+ } {
+ +
+ }
+ }
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+\newcount\mmlminuscounter
+
+\startsetups mml:minus
+ \doifelse \MMLsignreduction \v!yes {
+ \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
+ -\xmlfirst{#1}{/!mml:minus}
+ \else
+ \MMLdoL
+ \xmlsetup{#1}{mml:minus:reset}
+ \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
+ \MMLdoR
+ \fi
+ } {
+ \left( % \MMLdoL
+ \ifnum\xmlcount{#1}{/!mml:minus}=\plusone
+ -\xmlfirst{#1}{/!mml:minus}
+ \else
+ \xmlsetup{#1}{mml:minus:reset}
+ \xmlcommand{#1}{/!mml:minus}{mml:minus:body}
+ \fi
+ \right) % \MMLdoR
+ }
+\stopsetups
+
+\startxmlsetups mml:minus:reset
+ \mmlminuscounter\zerocount
+\stopxmlsetups
+
+\startxmlsetups mml:minus:body
+ % we can slso use concat here
+ \advance\mmlminuscounter\plusone
+ \ifnum\mmlminuscounter>\plusone
+ -
+ \fi
+ \xmldirect{#1}
+\stopxmlsetups
+
+% power
+
+\setupMMLappearance[power][\c!reduction=\v!yes]
+
+\let\MMLpowerelement\empty
+
+\startxmlsetups mml:power
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelse \MMLpowerreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist)} {
+ \gdef\MMLpowerelement{\mmlthird{#1}}% postpone, no xdef
+ \MMLcreset\mmlsecond{#1}
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+ } {
+ \mmlsecond{#1}\normalsuperscript{\MMLcreset\mmlthird{#1}}
+ }
+\stopxmlsetups
+
+% rem
+
+\startxmlsetups mml:rem
+ \xmlconcat{#1}{/!mml:rem}{\mathopnolimits{mod}}
+\stopxmlsetups
+
+\setupMMLappearance [times] [\c!symbol=\v!no,\c!auto=\v!yes] % new, auto catches cn cn cn
+
+\startxmlsetups mml:times
+ \setMMLcreset{\MMLcfunctionlist\string|\MMLcconstructlist}%
+ \doifelse\MMLtimesauto\v!no {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ } {
+ \xmldoifelse {#1} {/mml:cn[name(1) == 'mml:cn']} {% name(1) is next one
+ \doifelseinset\MMLtimessymbol{\v!yes,\v!no} {
+ \let\MMLtimes@@symbol\v!yes
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ } {
+ \let\MMLtimes@@symbol\MMLtimessymbol
+ }
+ }
+ \doifelse\MMLtimes@@symbol\v!yes {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \doifelse\MMLtimes@@symbol{dot} {
+ \xmlconcat{#1}{/!mml:times}{\cdot}
+ } {
+ \doifelse\MMLtimes@@symbol{times} {
+ \xmlconcat{#1}{/!mml:times}{\times}
+ } {
+ \xmlall{#1}{/!mml:times}
+ }
+ }
+ }
+\stopxmlsetups
+
+\setupMMLappearance[root][\c!symbol=\v!yes]
+
+\startxmlsetups mml:root
+ \xmldoifelse {#1} {/mml:degree} {
+ \root
+ \doifnot\MMLrootsymbol\v!no{\MMLcreset\xmltext{#1}{/mml:degree}}
+ \of
+ } {
+ \sqrt
+ }
+ {\MMLcreset\xmlall{#1}{/!(mml:degree\string|mml:root)}}
+\stopxmlsetups
+
+% gcd
+
+\startxmlsetups mml:gcd
+ \begingroup
+ \gcd\left(\MMLcreset\xmlconcat{#1}{/!mml:gcd}{\MMLseparator,}\right)
+ \endgroup
+\stopxmlsetups
+
+% and or xor implies, not
+
+\startxmlsetups mml:and \xmlconcat{#1}{/!mml:and} {\wedge} \stopxmlsetups
+\startxmlsetups mml:or \xmlconcat{#1}{/!mml:or} {\vee} \stopxmlsetups
+\startxmlsetups mml:xor \xmlconcat{#1}{/!mml:xor} {\mathopnolimits{xor}} \stopxmlsetups
+\startxmlsetups mml:implies \xmlconcat{#1}{/!mml:implies}{\Rightarrow} \stopxmlsetups
+\startxmlsetups mml:not \neg \xmlall {#1}{/!mml:not} \stopxmlsetups
+
+% forall exists
+
+%D We need to shift left below rotated A.
+
+\startxmlsetups mml:forall
+ \forall \negthinspace \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\startxmlsetups mml:exists
+ \exists \xmlsetup{#1}{mml:forallexists}
+\stopxmlsetups
+
+\def\mmlforallexistslist{mml:bvar\string|mml:forall\string|mml:exists\string|mml:condition}
+
+\startxmlsetups mml:forallexists
+ \normalsubscript{\xmlconcat{#1}{/mml:bvar}{\MMLseparator,}}
+ \xmldoifelse {#1} {/mml:condition} {
+ \thickspace
+ \begingroup
+ \xmlfirst{#1}{/mml:condition}
+ \endgroup
+ \ifcase\xmlcount{#1}{/!(\mmlforallexistslist)}\relax
+ % nothing
+ \or
+ % == snelle volgende
+ \left\vert
+ \MMLcreset \medspace \xmlconcat{#1}{/!(\mmlforallexistslist)}{}
+ \right.
+ \else
+ % special case
+ \left\vert
+ \matrix {
+ \xmlconcat{#1}{/!(\mmlforallexistslist)}{\hfill\crcr}
+ }
+ \right.
+ \fi
+ } {
+ :\xmlfirst{#1}{/!(\mmlforallexistslist)}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:abs
+ \left\vert \MMLcreset\xmlall{#1}{/!mml:abs} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:conjugate % watch extra {}
+ {\overline{\MMLcreset\xmlall{#1}{/!mml:conjugate}}}
+\stopxmlsetups
+
+\startxmlsetups mml:arg
+ \mathopnolimits{arg} \left( \MMLcreset\xmlall{#1}{/!mml:arg} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:real
+ \Re \left( \MMLcreset \xmlall{#1}{/!mml:real} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:imaginary
+ \Im \ left( \MMLcreset \xmlall{#1}{/!mml:imaginary} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:lcm
+ \mathopnolimits{lcm} \left( \xmlconcat{#1}{/!mml:lcm}{\MMLseparator,} \right)
+\stopxmlsetups
+
+\startxmlsetups mml:floor
+ \lfloor \xmlall{#1}{/!mml:floor} \rfloor
+\stopxmlsetups
+
+\startxmlsetups mml:ceiling
+ \lceiling \xmlall{#1}{/!mml:ceiling} \rceiling
+\stopxmlsetups
+
+% relations
+
+% apply attr or eq
+
+\setupMMLappearance[relation][\c!align=\v!no]
+
+\xmlmapvalue {mml:relation} {eq} {=}
+\xmlmapvalue {mml:relation} {neq} {\neq}
+\xmlmapvalue {mml:relation} {gt} {>}
+\xmlmapvalue {mml:relation} {lt} {<}
+\xmlmapvalue {mml:relation} {geq} {\geq}
+\xmlmapvalue {mml:relation} {leq} {\leq}
+\xmlmapvalue {mml:relation} {equivalent} {\equiv}
+\xmlmapvalue {mml:relation} {approx} {\approx}
+\xmlmapvalue {mml:relation} {factorof} {\mid}
+
+\startxmlsetups mml:eq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:neq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:gt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:lt \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:geq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:leq \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:equivalent \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:approx \xmlsetup{#1}{mml:relation} \stopxmlsetups
+\startxmlsetups mml:factorof \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+\startxmlsetups mml:relation
+ \edef\mmlapplyaction{\xmlfilter{#1}{/*/name()}}
+ \MMLcreset \xmlsetup{#1}{mml:relation:\xmlattdef{#1}{align}{\MMLrelationalign}}
+\stopxmlsetups
+
+\startxmlsetups mml:relation:default
+ \xmlconcatrange{#1}{/*}{2}{}{\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}}
+\stopxmlsetups
+\startxmlsetups mml:relation:last
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{-2}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
+ \mmlprelast{#1}&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}\mmllast{#1}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:first
+ \eqalign {
+ \mmlsecond{#1}\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}
+ &\xmlconcatrange{#1}{/*}{3}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:left
+ \eqalign {
+ \xmlconcatrange{#1}{/*}{2}{}{&\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}\crcr}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:right
+ \eqalign {
+ &\xmlconcatrange{#1}{/*}{2}{}{\crcr\xmlval{mml:relation}{\mmlapplyaction}{[\mmlapplyaction]}{}&}
+ }
+\stopxmlsetups
+\startxmlsetups mml:relation:no
+ \xmlsetup{#1}{mml:relation:default}
+\stopxmlsetups
+\startxmlsetups mml:relation:yes
+ \xmlsetup{#1}{mml:relation:left}
+\stopxmlsetups
+
+% personal goody:
+
+\edef\MMLcmainresetlist{\MMLcmainresetlist\string|becomes}
+
+\xmlmapvalue {mml:relation} {mml:becomes} {:=}
+
+\startxmlsetups mml:becomes \xmlsetup{#1}{mml:relation} \stopxmlsetups
+
+% calculus and vector calculus
+
+\startxmlsetups mml:domainofapplication
+ \xmlall{#1}{/!mml:domainofapplication}
+\stopxmlsetups
+
+\setupMMLappearance[int][\c!location=\v!top]
+
+\def\doMMLlimits#1{\doifelsevalue{MML#1\c!location}\v!top\limits\nolimits}
+
+\startxmlsetups mml:int
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:domainofapplication} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:domainofapplication}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:condition} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:condition}}\relax
+ } {
+ \xmldoifelse {#1} {/mml:lowlimit} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlfirst{#1}{/mml:lowlimit}}\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}
+ } {
+ % funny, why do we have lowlimit/uplimit then
+ \xmldoifelse {#1} {/mml:apply/mml:interval} {
+ \int \doMMLlimits{int}\normalsubscript{\xmlindex{#1}{/mml:apply}{2}}\normalsuperscript{\xmlindex{#1}{/mml:apply}{3}}
+ } {
+ \int
+ }
+ }
+ }
+ }
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:apply} {
+ \doifelsemmlfunction {#1} { % todo test
+ \xmlfirst{#1}{/mml:apply}
+ } {
+ % if there are too many () now, we need to be more clever
+ \left( \xmlfirst{#1}{/mml:apply} \right)
+ }
+ } {
+ \xmlfirst{#1}{/mml:ci}
+ }
+ \xmldoifelse {#1} {/mml:bvar} {
+ \thinspace {\mr d} \xmlfirst{#1}{/mml:bvar}
+ } {
+ % nothing
+ }
+\stopxmlsetups
+
+\setupMMLappearance[diff][\c!location=\v!top,\c!alternative=\v!a]
+
+\startxmlsetups mml:diff
+ \MMLcreset
+ \doifelse \MMLdiffalternative \v!a {
+ \xmldoifelse {#1} {/mml:lambda} {
+ % a special case (mathadore/openmath)
+ \mmlfrac {
+ d
+ \normalsuperscript
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ {\xmlfirst{#1}{/mml:lambda}\xmlfirst{#1}{/mml:ci}}
+ } {
+ d
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:ci}}
+ \normalsuperscript
+ {\xmlfirst{#1}{/mml:bvar}\xmlfirst{#1}{/mml:cn}}
+ }
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \mmlfrac {
+ {\mr d}{
+ \xmldoifelse {#1} {/mml:degree} {
+ \normalsuperscript{\xmlconcat{#1}{/mml:degree}\empty}
+ } {
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlconcat{#1}{/mml:bvar/mml:degree}+}
+ }
+ }
+ }
+ \doif \MMLdifflocation \v!top {
+ \xmldoifelse {#1} {/mml:ci} {
+ \xmlfirst{#1}{/mml:ci}
+ } {
+ \MMLcreset
+ \ifnum\xmlcount{#1}{/mml:apply/*}>\plustwo % hack
+ \left(\xmlfirst{#1}{/mml:apply}\right)
+ \else
+ \xmlfirst{#1}{/mml:apply}
+ \fi
+ }
+ }
+ } {
+ {\mr d}
+ \xmlfirst{#1}{/mml:bvar/!mml:degree}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ \doifnot \MMLdifflocation \v!top {
+ \left(\MMLcreset\xmlfirst{#1}{/(mml:apply\string|mml:ci)}\right)
+ }
+ } {
+ % beware, the second {} is needed for the superscript
+ \xmlconcatrange{#1}{/*}{2}{}{}\normalsuperscript\prime
+ }
+ }
+ } {
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:ci)}
+ % there can be problems with nested diff's: \normalsuperscript\normalsuperscript{} error
+ % so we add an empty group here
+ {}\normalsuperscript
+ {
+ \xmldoifelse {#1} {/mml:degree} {
+ \edef\mmldegree{\xmlfirst{#1}{/mml:degree/mml:cn}}
+ \ifx\mmldegree\empty
+ % what to do here
+ \else
+ \dorecurse\mmldegree\prime
+ \fi
+ } {
+ \prime
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:partialdiff
+ \xmldoifelse {#1} {/mml:list} {
+ {\mr D}\normalsubscript{
+ \begingroup
+ \setfalse\mmllistdelimiters
+ \xmlall{#1}{/mml:list}
+ \endgroup
+ }
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoifelse {#1} {/mml:bvar} {
+ \mmlfrac {
+ {\mr d}\normalsuperscript{
+ \xmldoifelse {#1} {/mml:degree} {
+ \xmlconcat{#1}{/mml:degree}\empty
+ } {
+ \xmlconcat{#1}{/mml:bvar/mml:degree}+
+ }
+ }
+ \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ } {
+ \xmldoif {#1}{/mml:bvar/!mml:degree} {
+ \xmlfirst{#1}{/mml:bvar/!mml:degree} \,
+ }
+ {\mr d}\xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ \xmldoif {#1} {/mml:bvar/mml:degree} {
+ \normalsuperscript{\xmlfirst{#1}{/mml:bvar/mml:degree}}
+ }
+ }
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:divergence \mathopnolimits{div} \xmlall{#1}{/!mml:divergence} \stopxmlsetups
+\startxmlsetups mml:grad \mathopnolimits{grad} \xmlall{#1}{/!mml:grad} \stopxmlsetups
+\startxmlsetups mml:curl \mathopnolimits{curl} \xmlall{#1}{/!mml:curl} \stopxmlsetups
+\startxmlsetups mml:laplacian \nabla\normalsuperscript2 \xmlall{#1}{/!mml:laplacian} \stopxmlsetups
+\startxmlsetups mml:ident \mathopnolimits{identity} \xmlall{#1}{/!mml:ident} \stopxmlsetups
+
+\setupMMLappearance[domain] [symbol=]
+\setupMMLappearance[codomain][symbol=]
+
+\startxmlsetups mml:domain
+ \doifelsenothing \MMLdomainsymbol {
+ \mathopnolimits{domain}\MMLcreset\xmlall{#1}{/!mml:domain}
+ } {
+ \MMLdomainsymbol\normalsubscript{\xmlall{#1}{/!mml:domain}}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:codomain
+ \doifelsenothing \MMLcodomainsymbol {
+ \mathopnolimits{codomain}\MMLcreset\xmlall{#1}{/!mml:codomain}
+ } {
+ \MMLcodomainsymbol\normalsubscript{\xmlall{#1}{/!mml:codomain}}
+ }
+\stopxmlsetups
+
+% theory of sets
+
+\startxmlsetups mml:set
+ \left\{
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:bvar}\,\middle\vert\,\xmlfirst{#1}{/mml:condition}
+ } {
+ \xmlconcat{#1}{/!mml:set}{\MMLseparator,}
+ }
+ \right\}
+ \relax % needed
+\stopxmlsetups
+
+\settrue\mmllistdelimiters
+
+\startxmlsetups mml:list
+ \begingroup
+ \ifconditional\mmllistdelimiters\left [\fi
+ \begingroup
+ \settrue\mmllistdelimiters
+ \xmlconcat{#1}{/!mml:list}{\MMLseparator,}
+ \endgroup
+ \ifconditional\mmllistdelimiters\right]\fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:union \mmlsecond{#1} \cup \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:intersect \mmlsecond{#1} \cap \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:in \mmlsecond{#1} \in \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notin \mmlsecond{#1} {\not\in} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:subset \mmlsecond{#1} \subset \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:prsubset \mmlsecond{#1} \subseteq \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notsubset \mmlsecond{#1} {\not\subset} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:notprsubset \mmlsecond{#1} {\not\subseteq} \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:setdiff \mmlsecond{#1} \setminus \mmlthird{#1} \stopxmlsetups
+
+\startxmlsetups mml:card
+ \left\vert \xmlall{#1}{/!mml:card} \right\vert
+\stopxmlsetups
+
+\startxmlsetups mml:cartesianproduct
+ \xmlconcat{#1}{/!mml:cartesianproduct}{\times}
+\stopxmlsetups
+
+% sequences and series
+
+\setupMMLappearance[sum] [\c!location=\v!top]
+\setupMMLappearance[product][\c!location=\v!top]
+
+\xmlmapvalue {mml:sumprod} {sum} {\sum}
+\xmlmapvalue {mml:sumprod} {product} {\prod}
+
+\startxmlsetups mml:sum \edef\mmlsumprodname{sum} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+\startxmlsetups mml:product \edef\mmlsumprodname{product} \xmlsetup{#1}{mml:sumprod} \stopxmlsetups
+
+\def\mmlstackedsubscripts#1%
+ {\vbox
+ {\baselineskip\zeropoint % hack, taco vragen
+ \halign{\startimath\scriptstyle\hss\alignmark\alignmark\hss\stopimath\cr#1\crcr}}}
+
+% unfinished
+
+\startxmlsetups mml:sumprod
+ \begingroup
+ \xmldoifelse {#1} {/(mml:condition\string|mml:bvar\string|mml:lowlimit)} {
+ \def\mmlsumprodlower{
+ \normalsubscript{
+ \xmldoifelse {#1} {/mml:condition} {
+ \mmlstackedsubscripts{\xmlconcat{#1}{/mml:condition}{\crcr}}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}
+ \xmldoif{#1}{/mml:lowlimit}{=}
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ }
+ } {
+ \let\mmlsumprodlower\empty
+ }
+ \xmldoifelse {#1} {/mml:uplimit} {
+ \def\mmlsumprodupper{\normalsuperscript{\xmlfirst{#1}{/mml:uplimit}}}
+ } {
+ \let\mmlsumprodupper\empty
+ }
+ \xmldoif {#1} {/mml:interval} { % open math converter gives this
+ \edef\mmlintervalfrom{\xmlindex{#1}{/mml:interval}{1}}
+ \edef\mmlintervalto {\xmlindex{#1}{/mml:interval}{2}}
+ \ifx \mmlintervalfrom \empty \else
+ \def\mmlsumprodlower{\normalsubscript{\xmldoif{#1}{/mml:bvar}{\xmlfirst{#1}{/mml:bvar}{=}}\mmlintervalfrom}}
+ \fi
+ \ifx \mmlintervalto \empty \else
+ \def\mmlsumprodupper{\normalsuperscript{\mmlintervalto}}
+ \fi
+ }
+ \MMLcreset
+ \xmlval{mml:sumprod}{\mmlsumprodname}{}\doMMLlimits\mmlsumprodname\mmlsumprodupper\mmlsumprodlower
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:lambda/mml:apply} {
+ \xmlfirst{#1}{/mml:lambda/mml:apply}% a bit of open math conversion mess
+ } {
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda\string|mml:ci)}%
+ }
+ \endgroup
+\stopxmlsetups
+
+\setupMMLappearance[limit][\c!location=\v!top]
+
+\startxmlsetups mml:limit
+ \MMLcreset \lim
+ \doMMLlimits {limit}\normalsubscript{
+ \MMLcreset
+ \xmldoifelse {#1} {/mml:condition} {
+ \xmlfirst{#1}{/mml:condition}
+ } {
+ \xmldoif {#1} {/mml:bvar} {
+ \xmlfirst{#1}{/mml:bvar}\rightarrow
+ }
+ \xmlfirst{#1}{/mml:lowlimit}
+ }
+ }
+ \begingroup
+ % a bit of open math conversion mess, lambda needed for openmath, ok?
+ \MMLcreset
+ \xmlfirst{#1}{/mml:lambda/mml:apply}
+ \xmlfirst{#1}{/(mml:apply\string|mml:lambda)}
+ \endgroup
+\stopxmlsetups
+
+% consider a faster index
+
+\startxmlsetups mml:tendsto
+ \MMLcreset \mmlsecond{#1}
+ \xmlval {mml:tendsto:type} {\xmlattdef{#1}{type}{default}} {\rightarrow}
+ \MMLcreset \mmlthird{#1}
+\stopxmlsetups
+
+\xmlmapvalue {mml:tendsto:type} {above} {\downarrow}
+\xmlmapvalue {mml:tendsto:type} {below} {\uparrow}
+\xmlmapvalue {mml:tendsto:type} {default} {\rightarrow}
+
+% elementary classical functions
+
+\setupMMLappearance[log][\c!location=\v!right]
+
+\startxmlsetups mml:exp
+% {\mr e}\normalsuperscript{\xmlfirst{#1}{/mml:apply\string|mml:reln\string|mml:ci\string|mml:cn}}
+ {\mr e}\normalsuperscript{\xmlfirst{#1}{/!mml:exp}}
+\stopxmlsetups
+
+\startxmlsetups mml:log
+ \xmldoifelse {#1} {/mml:logbase} {
+ \doifelse \MMLloglocation \v!left {
+ \mathop {
+ {}\normalsuperscript{\xmlfirst{#1}{/mml:logbase}}\negthinspace\mathopnolimits{log}
+ }
+ } {
+ \mathopnolimits{log}\normalsubscript{\xmlfirst{#1}{/mml:logbase}}
+ }
+% \MMLcreset
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+% \xmlsetup{#1}{mml:function} % todo, we start elsewhere
+% \mmlthird{#1}
+ } {
+ \mathopnolimits{log}
+% \MMLcreset
+% \xmlsetup{#1}{mml:function} % todo, we start elsewhere
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}
+% \mmlsecond{#1}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:ln
+ \mathopnolimits{ln}
+ \xmlsetup{#1}{mml:function}
+\stopxmlsetups
+
+% statistics
+
+\startxmlsetups mml:mean \overline {\mmlsecond{#1}} \stopxmlsetups
+\startxmlsetups mml:sdev \sigma \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:variance \sigma \left(\MMLcreset\mmlsecond{#1}\right)\normalsuperscript2 \stopxmlsetups
+\startxmlsetups mml:median \mathopnolimits{median}\left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+\startxmlsetups mml:mode \mathopnolimits{mode} \left(\MMLcreset\mmlsecond{#1}\right) \stopxmlsetups
+
+% moments
+
+\startxmlsetups mml:moment
+ \left\langle
+ \xmlfirst{#1}{/(mml:apply\string|mml:reln\string|mml:ci\string|mml:cn)}\normalsuperscript{\xmlfirst{#1}{/mml:degree}}
+ \right\rangle
+ \xmldoif {#1} {mml:momentabout} {
+ \normalsubscript{\xmlfirst{#1}{mml:momentabout}}
+ }
+\stopxmlsetups
+
+% linear algebra
+
+\setupMMLappearance [vector] [\c!direction=\v!horizontal,\c!separator={,}]
+
+\startxmlsetups mml:vector
+ \begingroup
+ \ifnum\xmlcount{#1}{/*}>\plusone
+ \doifelse\MMLvectordirection\v!horizontal {
+ \left(\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}\right)
+ } {
+ \MMLcreset\left(\matrix{\xmlconcat{#1}{/*}{\MMLseparator\MMLvectorseparator}}\right)
+ }
+ \else
+ \overrightarrow{\charhtstrut\mmlfirst{#1}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\settrue\MMCdelmatrix % ( ) when true
+
+\startxmlsetups mml:matrix
+ \begingroup
+ \MMLcreset
+ \ifconditional\MMCdelmatrix
+ \left(\matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}\right)
+ \else
+ \settrue\MMCdelmatrix
+ \matrix{\xmlcommand{#1}{/mml:matrixrow}{mml:matrixrow:do}}
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow
+ \begingroup
+ \MMLcreset
+ \left(\xmlsetup{#1}{mml:matrixrow:do}\right)
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:matrixrow:do
+ \xmlconcat{#1}{/*}{&}\crcr
+\stopxmlsetups
+
+\startxmlsetups mml:determinant
+ \begingroup
+ \setfalse\MMCdelmatrix
+ \left|\mmlsecond{#1}\right|
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:transpose
+ \mmlsecond{#1}\normalsuperscript{\mathopnolimits{T}}
+\stopxmlsetups
+
+\startxmlsetups mml:selector
+ \MMLmathinner{\mmlsecond{#1}\normalsubscript{\MMLcreset\xmlconcatrange{#1}{/*}{3}{}{\MMLseparator,}}}
+\stopxmlsetups
+
+\startxmlsetups mml:vectorproduct \mmlsecond{#1}\times \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:scalarproduct \mmlsecond{#1}\cdot \mmlthird{#1} \stopxmlsetups
+\startxmlsetups mml:outerproduct \mmlsecond{#1}\otimes\mmlthird{#1} \stopxmlsetups
+
+% semantic mapping elements
+
+\setupMMLappearance[semantics][\c!state=\v!start]
+
+\startxmlsetups mml:semantics
+ \doifelse\MMLsemanticsstate\v!start {
+ \xmlall{#1}{/mml:annotation}
+ } {
+ \xmlall{#1}{/!mml:annotation}
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:annotation
+ \xmldoifelse {#1} {.[oneof(@encoding,'TeX','tex','application/x-tex','TEX','ConTeXt','context','CONTEXT','ctx')]} {
+ \xmlflushcontext{#1}
+ } {
+ \xmldoifelse {#1} {.[oneof(@encoding,'calcmath','cm')]} {
+ \expanded{\calcmath{\xmlflush{#1}}}
+ } {
+ \xmldoifelse {#1} {.[oneof(@encoding,'asciimath','am')]} {
+ \ifdefined\asciimath
+ \expanded{\asciimath{\xmlflush{#1}}}
+ \else
+ \hbox{\tt no am loaded}
+ \fi
+ } {
+ \xmlall{#1}{../!mml:annotation}
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:annotation-xml
+ % maybe diagnostics
+\stopxmlsetups
+
+% misc
+
+\startxmlsetups mml:integers \integers \stopxmlsetups
+\startxmlsetups mml:reals \reals \stopxmlsetups
+\startxmlsetups mml:rationals \rationals \stopxmlsetups
+\startxmlsetups mml:naturalnumbers \naturalnumbers \stopxmlsetups
+\startxmlsetups mml:complexes \complexes \stopxmlsetups
+\startxmlsetups mml:primes \primes \stopxmlsetups
+\startxmlsetups mml:exponentiale \mathopnolimits{e} \stopxmlsetups
+\startxmlsetups mml:imaginaryi \mathopnolimits{i} \stopxmlsetups
+\startxmlsetups mml:notanumber \mathopnolimits{NaN} \stopxmlsetups
+\startxmlsetups mml:true \mathopnolimits{true} \stopxmlsetups
+\startxmlsetups mml:false \mathopnolimits{false} \stopxmlsetups
+\startxmlsetups mml:emptyset \mathopnolimits{Ø} \stopxmlsetups
+\startxmlsetups mml:pi \pi \stopxmlsetups
+\startxmlsetups mml:eulergamma \gamma \stopxmlsetups
+\startxmlsetups mml:infinity \infty \stopxmlsetups
+
+% gonio functions
+
+\setupMMLappearance[function][\c!reduction=\v!yes]
+
+% todo: \mfunction which adapts itself when registered as command
+
+% todo: \def\mmlcfunction#1#2{\mathopnolimits{#2}\xmlsetup{#1}{mml:function}}
+
+\startxmlsetups mml:sin \mathcommand {sin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sinh \mathcommand {sinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cos \mathcommand {cos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cosh \mathcommand {cosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tan \mathcommand {tan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:tanh \mathcommand {tanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:cot \mathcommand {cot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:coth \mathcommand {coth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csc \mathcommand {csc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:csch \mathcommand {csch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sec \mathcommand {sec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:sech \mathcommand {sech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+
+\startxmlsetups mml:arcsin \mathcommand {arcsin}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsinh \mathcommand{arcsinh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccos \mathcommand {arccos}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccosh \mathcommand{arccosh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arctan \mathcommand {arctan}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arctanh \mathcommand{arctanh}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccot \mathcommand {arccot}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccoth \mathcommand{arccoth}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccsc \mathcommand {arccsc}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arccsch \mathcommand{arccsch}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsec \mathcommand {arcsec}\xmlsetup{#1}{mml:function} \stopxmlsetups
+\startxmlsetups mml:arcsech \mathcommand{arcsech}\xmlsetup{#1}{mml:function} \stopxmlsetups
+
+\startxmlsetups mml:function
+ \ifx\MMLpowerelement\empty
+ \ifconditional\xmlinversefunction\normalsuperscript{-1}\fi
+ \setfalse\xmlinversefunction
+ \else
+ \normalsuperscript{\ifconditional\xmlinversefunction-\fi\MMLpowerelement}
+ \setfalse\xmlinversefunction
+ \glet\MMLpowerelement\empty
+ \fi
+ \xmlsetup{#1}{mml:function:argument}
+\stopxmlsetups
+
+\startxmlsetups mml:function:argument
+ \doifelse \MMLfunctionreduction \v!yes {
+ \xmldoifelse {#1} {/mml:apply} {
+ \xmldoifelse {#1} {/mml:apply/(\MMLcfunctionlist\string|mml:divide)}
+ \donefalse
+ \donetrue
+ } {
+ \donefalse
+ }
+ } {
+ \donetrue
+ }
+ % beware, we still flush from 2 up
+ \ifdone
+ \left(
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}% \xmlconcatrange{#1}{/*}{2}{}\empty
+ \right)
+ \else
+ \MMLcreset
+ \xmlall{#1}{/[position()>1]}
+ \fi
+\stopxmlsetups
+
+% PRESENTATION MATHML
+
+% helpers: maybe we can need a setting for the uprights
+
+\xmlmapvalue {mml:s} {normal} {\mathupright} % {\mathtf}
+\xmlmapvalue {mml:s} {double-struck} {\mathblackboard}
+\xmlmapvalue {mml:s} {italic} {\mathit}
+\xmlmapvalue {mml:s} {fraktur} {\mathfraktur}
+\xmlmapvalue {mml:s} {script} {\mathscript}
+\xmlmapvalue {mml:s} {bold} {\mb} % {\mathbf}
+\xmlmapvalue {mml:s} {bold-italic} {\mathbi}
+\xmlmapvalue {mml:s} {bold-fraktur} {\mathfraktur\mathbf}
+\xmlmapvalue {mml:s} {bold-script} {\mathscript\mathbf}
+\xmlmapvalue {mml:s} {sans-serif} {\mathss}
+\xmlmapvalue {mml:s} {bold-sans-serif} {\mathss\mathbf}
+\xmlmapvalue {mml:s} {sans-serif-italic} {\mathss\mathit}
+\xmlmapvalue {mml:s} {sans-serif-bold-italic} {\mathss\mathbi}
+\xmlmapvalue {mml:s} {monospace} {\mathtt}
+
+\xmlmapvalue {mml:l} {-} {\let\mmlfrac\tfrac}
+ \let\mmlfrac\frac
+\xmlmapvalue {mml:l} {+} {\let\mmlfrac\sfrac}
+
+% todo: displaystyle=true/false (or whatever else shows up)
+
+\starttexdefinition setmmlmathstyle #1
+ \xmlval{mml:s}{\xmlatt{#1}{mathvariant}}\empty % was: \mmmr
+\stoptexdefinition
+
+\starttexdefinition setmmlscriptlevel #1
+ \xmlval{mml:l}{\xmlatt{#1}{scriptlevel}}{\let\mmlfrac\frac}
+\stoptexdefinition
+
+\starttexdefinition applymmlmathcolor #1#2
+ \edef\mmlmathcolor{\xmlatt{#1}{mathcolor}}
+ \ifx \mmlmathcolor \empty
+ #2
+ \else
+ \color[\mmlmathcolor]{#2}
+ \fi
+\stoptexdefinition
+
+% todo: textbackgrounds
+
+\starttexdefinition applymmlmathbackground #1#2
+ \edef\mmlmathbackground{\xmlatt{#1}{mathbackground}}
+ \ifx \mmlmathbackground \empty
+ #2
+ \else
+ \backgroundline[\mmlmathbackground]{#2}
+ \fi
+\stoptexdefinition
+
+\newsignal\mmltextsignal % not used
+
+\starttexdefinition applymmlsometext #1#2
+ \applymmlmathbackground {#1} {
+ \applymmlmathcolor {#1} {
+ \setmmlmathstyle {#1}
+ #2
+ }
+ }
+\stoptexdefinition
+
+% probably bugged:
+
+\starttexdefinition doMMLfiller #1
+ \pushmacro\doMMLfiller
+ \let\doMMLfiller\gobbleoneargument
+ \gdef\dodoMMLfiller{% where used
+ \disablefiller
+ \mathematics{#1}
+ }
+ \hbox {
+ \def\normalorfiller##1##2{
+ \gdef\dodoMMLfiller{\enablefiller#1}%
+ \let\normalorfiller\gobbletwoarguments
+ }
+ \mathematics{#1}
+ }
+ \popmacro\doMMLfiller
+\stoptexdefinition
+
+% setups
+
+\startxmlsetups mml:mi % todo: mathsize (unlikely) mathcolor (easy) mathbackground (easy)
+ \begingroup
+ \pushmathstyle
+ \setmmlmathstyle{#1}
+ \setmmlscriptlevel{#1}
+ \ctxmodulemathml{mi("#1")}
+ \popmathstyle
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:mn
+ \ctxmodulemathml{mn("#1")}% no \hbox, would be ok for . , but spoils rest
+\stopxmlsetups
+
+% <m:mo>-</m:mo><m:mn>2</m:mn> and <m:mn>1</m:mn><m:mo>-</m:mo><m:mn>2</m:mn>
+%
+% spacing between - and 2 is taken care of by tex itself
+
+\startxmlsetups mml:mo
+ \doif {\xmlatt{#1}{maxsize}} {1} {\settrue\mmlignoredelimiter}
+ \doif {\xmlatt{#1}{stretchy}} {false} {\settrue\mmlignoredelimiter}
+ \ctxmodulemathml{mo("#1")}
+ \setfalse\mmlignoredelimiter
+\stopxmlsetups
+
+% \startxmlsetups mml:mfenced % {} around separator is needed for spacing
+% \def\MMLleft {\left }% weird
+% \def\MMLright {\right}
+% \def\MMLmiddle{\middle}
+% \ctxmodulemathml{mfenced("#1")}
+% \stopxmlsetups
+
+\startxmlsetups mml:mfenced % {} around separator is needed for spacing
+ %\math_fences_checked_start
+ \ctxmodulemathml{mfenced("#1")}
+ %\math_fences_checked_stop
+\stopxmlsetups
+
+
+\defineoverlay [mml:enclose:box] [\useMPgraphic{mml:enclose:box}]
+\defineoverlay [mml:enclose:roundedbox] [\useMPgraphic{mml:enclose:roundedbox}]
+\defineoverlay [mml:enclose:circle] [\useMPgraphic{mml:enclose:circle}]
+\defineoverlay [mml:enclose:left] [\useMPgraphic{mml:enclose:left}]
+\defineoverlay [mml:enclose:right] [\useMPgraphic{mml:enclose:right}]
+\defineoverlay [mml:enclose:top] [\useMPgraphic{mml:enclose:top}]
+\defineoverlay [mml:enclose:bottom] [\useMPgraphic{mml:enclose:bottom}]
+\defineoverlay [mml:enclose:updiagonalstrike] [\useMPgraphic{mml:enclose:updiagonalstrike}]
+\defineoverlay [mml:enclose:downdiagonalstrike] [\useMPgraphic{mml:enclose:downdiagonalstrike}]
+\defineoverlay [mml:enclose:horizontalstrike] [\useMPgraphic{mml:enclose:horizontalstrike}]
+\defineoverlay [mml:enclose:verticalstrike] [\useMPgraphic{mml:enclose:verticalstrike}]
+
+\startuseMPgraphic{mml:enclose:box}
+ draw OverlayBox withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:roundedbox}
+ draw OverlayBox cornered .5ExHeight withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:circle}
+ draw fullcircle xysized(bbwidth(OverlayBox),bbheight(OverlayBox)) withpen pencircle scaled (ExHeight/10) ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:left}
+ draw leftboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:right}
+ draw rightboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:top}
+ draw topboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:bottom}
+ draw bottomboundary OverlayBox withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:updiagonalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw llcorner p -- urcorner p withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:downdiagonalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw ulcorner p -- lrcorner p withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:horizontalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw .5[llcorner p,ulcorner p] -- .5[lrcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+\startuseMPgraphic{mml:enclose:verticalstrike}
+ path p ; p := OverlayBox enlarged -.25ExHeight ;
+ draw .5[llcorner p,lrcorner p] -- .5[ulcorner p,urcorner p] withpen pencircle scaled (ExHeight/10) ;
+ setbounds currentpicture to OverlayBox ;
+\stopuseMPgraphic
+
+\startxmlsetups mml:menclose
+ \edef\mmlmenclosenotation{\ctxmodulemathml{menclosepattern("#1")}}
+ \ifx\mmlmenclosenotation\empty
+ \xmlflush{#1}
+ \else
+ \doifelse \mmlmenclosenotation {mml:enclose:longdiv} {
+ \overline{\left)\strut\xmlflush{#1}\right.}
+ } {
+ \doifelse \mmlmenclosenotation {mml:enclose:actuarial} {
+ \overline{\left.\strut\xmlflush{#1}\right\vert}
+ } {
+ \doifelse \mmlmenclosenotation {mml:enclose:radical} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ % todo: no framed when longdiv, actuarial or radical ? spec ?
+ \vcenter {
+ \framed
+ [frame=off,strut=no,background={\mmlmenclosenotation}] % offset is kind of undefined
+ {\startimath
+ \expanded{\doifelseinset {mml:enclose:longdiv} {\mmlmenclosenotation}} {
+ \overline{\left)\strut\xmlflush{#1}\right.}
+ } {
+ \expanded{\doifelseinset {mml:enclose:actuarial} {\mmlmenclosenotation}} {
+ \overline{\left.\strut\xmlflush{#1}\right\vert}
+ } {
+ \expanded{\doifelseinset {mml:enclose:radical} {\mmlmenclosenotation}} {
+ \sqrt{\xmlflush{#1}}
+ } {
+ \xmlflush{#1}
+ }
+ }
+ }
+ \stopimath}
+ }
+ }
+ }
+ }
+ \fi
+\stopxmlsetups
+
+\xmlmapvalue {mml:mfrac:linethickness} {thin} {.2pt}
+\xmlmapvalue {mml:mfrac:linethickness} {medium} {.4pt}
+\xmlmapvalue {mml:mfrac:linethickness} {thick} {.8pt}
+\xmlmapvalue {mml:mfrac:linethickness} {0} {0pt}
+
+\startxmlsetups mml:mfrac % dodo: handle linethickness in lua + unit
+ \begingroup
+ \edef\mmlfraclinethickness{\xmlatt{#1}{linethickness}}
+ \ifx\mmlfraclinethickness\empty
+ \doifelse{\xmlatt{#1}{bevelled}}{true} {
+ \left.\mmlfirst{#1}\middle/\mmlsecond{#1}\right.% \thinspace\middle/\thinspace
+ } {
+ \mmlfrac{\mmlfirst{#1}}{\mmlsecond{#1}}
+ }
+ \else
+ \doifelse {\xmlval{mml:mfrac:linethickness}{\mmlfraclinethickness}{}} {} {
+ \scratchdimen\xmlval{mml:mfrac:linethickness}\mmlfraclinethickness{.4pt}
+ } {
+ % probably not yet ok
+ \setdimensionwithunit\scratchdimen\mmlfraclinethickness{pt}
+ }
+ {
+ {\mmlfirst{#1}}
+ \above\scratchdimen
+ {\mmlsecond{#1}}
+ }
+ \fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:ms
+ \hbox {
+ \tf % else encoding problems
+ \edef\mmllquote{\xmlatt{#1}{lquote}}
+ \edef\mmlrquote{\xmlatt{#1}{rquote}}
+ \ifx\mmllquote\empty\symbol[leftquotation]\else\mmllquote\fi
+ \applymmlsometext{#1}{\xmlflush{#1}}
+ \ifx\mmlrquote\empty\symbol[rightquotation]\else\mmlrquote\fi
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mstyle
+ \begingroup
+ \pushmathstyle
+ \setmmlmathstyle{#1}
+ \setmmlscriptlevel{#1}
+ \xmlflush{#1}
+ \popmathstyle
+ \endgroup
+\stopxmlsetups
+
+\setupMMLappearance[text][\c!alternative=\v!b] % a=normal, b=keep spaces
+
+\startxmlsetups mml:mtext
+ \text {
+ \applymmlsometext{#1}{
+ \doifelse \MMLtextalternative \v!a {
+ %\ctxmodulemathml{stripped(\!!bs\xmlflush{#1}\!!es)}
+ \ignorespaces
+ \xmlflush{#1}
+ \removeunwantedspaces
+ } {
+ \xmlflush{#1}
+ }
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:merror
+ \hbox{\startimath\displaystyle\xmlflush{#1}\stopimath}
+\stopxmlsetups
+
+\startxmlsetups mml:mphantom
+% \phantom{\ignorespaces{}\xmlflush{#1}\unskip} % watch spacing {} hack
+% \phantom{\mathstyle{\ignorespaces{}\xmlflush{#1}\unskip}}%
+ \phantom{\triggermathstyle\normalmathstyle\ignorespaces\xmlflush{#1}\removeunwantedspaces}
+% \mktriggereffect\v!hidden
+% \ignorespaces{}\xmlflush{#1}\unskip % no attributes in math yet
+% \mktriggereffect\v!normal
+\stopxmlsetups
+
+\startxmlsetups mml:mpadded % todo
+ \xmlflush{#1}
+\stopxmlsetups
+
+% mrow / option: no fenced
+
+\startxmlsetups mml:maction
+ \xmlflush{#1}
+\stopxmlsetups
+
+% \startxmlsetups mml:mrow
+% \begingroup
+% \edef\nofmmlrows{\xmlcount{#1}{/mml:mo}}%
+% \ifnum\nofmmlrows=\plustwo
+% \xmldoifelse {#1} {/mml:mo[position()==1 or position()==\nofmmlrows]} {% we need a {}
+% \def\MMLleft {\left }
+% \def\MMLright {\right}
+% \def\MMLmiddle{\middle}
+% \enabledelimiter
+% \checkdelimiters{\xmlall{#1}{/mml:mo}}
+% \fakeleftdelimiter
+% \xmlflush{#1}
+% \fakerightdelimiter
+% \disabledelimiter
+% } {
+% \xmlflush{#1}
+% }
+% \else
+% \xmlflush{#1}
+% \fi
+% \endgroup
+% \stopxmlsetups
+%
+% fails on { ... so we need
+
+% \startxmlsetups mml:mrow
+% \begingroup
+% \xmldoifelse {#1} {/mml:mo[first() or last()]} {% we need a {}
+% \def\MMLleft {\left }
+% \def\MMLright {\right}
+% \def\MMLmiddle{\middle}
+% \enabledelimiter
+% \checkdelimiters{\xmlall{#1}{/mml:mo}}
+% \fakeleftdelimiter
+% \xmlflush{#1}
+% \fakerightdelimiter
+% \disabledelimiter
+% } {
+% \xmlflush{#1}
+% }
+% \endgroup
+% \stopxmlsetups
+%
+% more modern:
+
+\startxmlsetups mml:mrow
+ \begingroup
+ %\xmldoifelse {#1} {/mml:mo[first() or last()]} {% we need a {}
+ % % \math_fences_checked_start
+ % \xmlflush{#1}
+ % \math_fences_checked_stop
+ %} {
+ \xmlflush{#1}
+ %}
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:msqrt
+ \sqrt{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups mml:mroot
+ \root{\mmlsecond{#1}}\of{\mmlfirst{#1}}
+\stopxmlsetups
+
+\setupMMLappearance[scripts][\c!alternative=\v!a] % {} rond base
+
+% brrr no { } when limop .. todo: better in lua
+% speed up with ifx and setups or just in lua
+
+\let\mmlnucleus\relax
+
+\startxmlsetups mml:msub
+ \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}}
+ \doifelse {\utfmathclass\mmlnucleus} {limop} {
+ \mmlfirst{#1} \normalsubscript{\mmlsecond{#1}}
+ } {
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}\normalsubscript{\mmlsecond{#1}}
+ } {
+ \mmlfirst{#1} \normalsubscript{\mmlsecond{#1}}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:msup
+ \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}}
+ \doifelse {\utfmathclass\mmlnucleus} {limop} {
+ \mmlfirst{#1} \normalsuperscript{\mmlsecond{#1}}
+ } {
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}\normalsuperscript{\mmlsecond{#1}}
+ } {
+ \mmlfirst{#1} \normalsuperscript{\mmlsecond{#1}}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:msubsup
+ \edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}}
+ \doifelse {\utfmathclass\mmlnucleus} {limop} {
+ \mmlfirst{#1}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}}
+ } {
+ \doifelse\MMLscriptsalternative\v!a {
+ {\mmlfirst{#1}}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}}
+ } {
+ \mmlfirst{#1}\normalsubscript{\mmlsecond{#1}}\normalsuperscript{\mmlthird{#1}}
+ }
+ }
+\stopxmlsetups
+
+% helpers
+
+\unexpanded\def\mmlexecuteifdefined#1%
+ {\ifx#1\empty
+ \expandafter\secondoftwoarguments
+ \else\ifcsname#1\endcsname
+ \doubleexpandafter\firstoftwoarguments
+ \else
+ \doubleexpandafter\secondoftwoarguments
+ \fi\fi
+ {\csname#1\endcsname}}
+
+\def\mmlextensible#1{\ctxmodulemathml{extensible(\!!bs#1\!!es)}}
+
+\definemathtriplet [\v!mathematics] [mmlovertriplet] % or will we use a special instance
+\definemathtriplet [\v!mathematics] [mmlundertriplet] % or will we use a special instance
+\definemathtriplet [\v!mathematics] [mmldoubletriplet] % or will we use a special instance
+
+% common to munder/mover/munderover : will become core helper (speed up too)
+
+\starttexdefinition unexpanded mmlfencedfirst #1
+ %\math_fences_checked_start
+ \mmlunexpandedfirst{#1}
+ %\math_fences_checked_stop
+\stoptexdefinition
+\starttexdefinition unexpanded mmlfencedsecond #1
+ %\math_fences_checked_start
+ \mmlunexpandedsecond{#1}
+ %\math_fences_checked_stop
+\stoptexdefinition
+\starttexdefinition unexpanded mmlfencedthird #1
+ %\math_fences_checked_start
+ \mmlunexpandedthird{#1}
+ %\math_fences_checked_stop
+\stoptexdefinition
+
+% mover
+
+\starttexdefinition unexpanded mmloverabove #1
+ \edef\mmlovercommand{\utfmathfiller\mmlovertoken}
+ \mmlexecuteifdefined\mmlovercommand {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition unexpanded mmloverbase #1
+ \edef\mmlbasecommand{\utfmathfiller\mmlbasetoken}
+ \mmlexecuteifdefined\mmlbasecommand {\mmlfencedfirst{#1}}
+ \relax
+\stoptexdefinition
+\starttexdefinition unexpanded mmloverbasefiller #1
+ \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}
+ \mmlexecuteifdefined\mmlbasecommand \relax {\mmlfencedsecond{#1}} {}
+\stoptexdefinition
+\starttexdefinition unexpanded mmloveraccent #1
+ \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken}
+ \mmlexecuteifdefined\mmlovercommand \relax {\mmlfencedfirst{#1}}
+\stoptexdefinition
+\starttexdefinition unexpanded mmlovertext #1
+ \mmlovertriplet {\mmloverbase{#1}} {\mmloverabove{#1}} {}
+\stoptexdefinition
+\starttexdefinition unexpanded mmloveraccentchecker #1
+ \edef\mmlovertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \doifelseutfmathabove\mmlovertoken \mmloveraccent \mmlovertext {#1}
+\stoptexdefinition
+
+\startxmlsetups mml:mover
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathfiller\mmlbasetoken \mmloverbasefiller \mmloveraccentchecker {#1}
+\stopxmlsetups
+
+% munder
+
+\starttexdefinition unexpanded mmlunderbelow #1
+ \edef\mmlundercommand{\utfmathfiller\mmlundertoken}
+ \mmlexecuteifdefined\mmlundercommand {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderbase #1
+ \edef\mmlbasecommand{\utfmathfiller\mmlbasetoken}
+ \mmlexecuteifdefined\mmlbasecommand {\mmlfencedfirst{#1}}
+ \relax
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderbasefiller #1
+ \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}%
+ \mmlexecuteifdefined\mmlbasecommand \relax {} {\mmlfencedsecond{#1}}
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderaccent #1
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \mmlexecuteifdefined\mmlundercommand \relax {\mmlfencedfirst{#1}}
+\stoptexdefinition
+\starttexdefinition unexpanded mmlundertext #1
+ \mmlundertriplet {\mmlunderbase{#1}} {} {\mmlunderbelow{#1}}
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderaccentchecker #1
+ \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \doifelseutfmathbelow\mmlundertoken \mmlunderaccent \mmlundertext {#1}
+\stoptexdefinition
+
+\startxmlsetups mml:munder
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathfiller\mmlbasetoken \mmlunderbasefiller \mmlunderaccentchecker {#1}
+\stopxmlsetups
+
+% munderover
+
+\starttexdefinition unexpanded mmlunderoveraccentcheckerUO #1
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \edef\mmlovercommand {\utfmathcommandabove\mmlovertoken}
+ \edef\mmlbasecommand {\mmlovercommand\mmlundercommand}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}}
+ \else\ifcsname\mmlundercommand\endcsname
+ \ifcsname\mmlovercommand\endcsname
+ \lastnamedcs {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}}
+ \else
+ \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}\mmlfencedthird{#1}} {}
+ \fi
+ \else\ifcsname\mmlovercommand\endcsname
+ \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi\fi\fi
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderoveraccentcheckerUT #1
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \edef\mmlbasecommand {\mmlundercommand text}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}}
+ \else\ifcsname\mmlundercommand\endcsname
+ \mmldoubletriplet {\csname\mmlundercommand\endcsname{\mmlfencedfirst{#1}}} {\mmlfencedthird{#1}} {}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi\fi
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderoveraccentcheckerOT #1
+ \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken}
+ \edef\mmlbasecommand{\mmlovercommand text}
+ \ifcsname\mmlbasecommand\endcsname
+ \lastnamedcs {\mmlfencedfirst{#1}} {\mmlfencedsecond{#1}}
+ \else\ifcsname\mmlovercommand\endcsname
+ \mmldoubletriplet {\csname\mmlovercommand\endcsname{\mmlfencedfirst{#1}}} {} {\mmlfencedsecond{#1}}
+ \else
+ \mmlunderoveraccentcheckerTT {#1}
+ \fi\fi
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderoveraccentcheckerTT #1
+ \mmldoubletriplet {\mmlfencedfirst{#1}} {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}} \relax
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderoveraccentchecker #1
+ \edef\mmlundertoken{\mmlextensible{\xmlraw{#1}{/mml:*[2]}}}% /text()
+ \edef\mmlovertoken {\mmlextensible{\xmlraw{#1}{/mml:*[3]}}}% /text()
+ \doifelseutfmathbelow\mmlundertoken {
+ \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerUO \mmlunderoveraccentcheckerUT {#1}
+ } {
+ \doifelseutfmathabove\mmlovertoken \mmlunderoveraccentcheckerOT \mmlunderoveraccentcheckerTT {#1}
+ }
+\stoptexdefinition
+\starttexdefinition unexpanded mmlunderoverbasefiller #1
+ \edef\mmlbasecommand{e\utfmathcommandfiller\mmlbasetoken}%
+ \mmlexecuteifdefined\mmlbasecommand \relax {\mmlfencedthird{#1}} {\mmlfencedsecond{#1}}
+\stoptexdefinition
+\startxmlsetups mml:munderover
+ \edef\mmlbasetoken{\mmlextensible{\xmlraw{#1}{/mml:*[1]}}}% /text()
+ \doifelseutfmathfiller\mmlbasetoken \mmlunderoverbasefiller \mmlunderoveraccentchecker {#1}
+\stopxmlsetups
+
+% tables (mml:mtable, mml:mtr, mml:mlabledtr, mml:mtd)
+
+\startxmlsetups mml:mtable % some more attributes need to be supported
+ \vcenter {
+ \hbox {% needed because otherwise positions makr the vcenter wide
+ \ctxmodulemathml{mtable("#1")}
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups mml:mcolumn
+ \ctxmodulemathml{mcolumn("#1")}
+\stopxmlsetups
+
+\def\mmlsetfakewidth#1{\setbox\scratchbox\hbox{#1}\scratchdimen\wd\scratchbox}
+
+\def\mmlmcolumndigitspace {\mmlsetfakewidth {0}\kern\scratchdimen}
+\def\mmlmcolumndigitrule {\mmlsetfakewidth {0}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+\def\mmlmcolumnsymbolrule {\mmlsetfakewidth{\times}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+\def\mmlmcolumnpunctuationrule{\mmlsetfakewidth {.}\vrule \s!width \scratchdimen \s!height .2\points \s!depth .2\points\relax}
+
+\setupMMLappearance[mspace][\c!option=] % \v!test
+
+\startxmlsetups mml:mspace
+ \begingroup
+ \edef\mmlspacetext{\xmlatt{#1}{spacing}}
+ \ifx\mmlspacetext\empty
+ \scratchwidth \xmlattdef{#1}{width} \!!zeropoint % must be string
+ \scratchheight\xmlattdef{#1}{height}\!!zeropoint
+ \scratchdepth \xmlattdef{#1}{depth} \!!zeropoint
+ \ifdim\scratchheight=\zeropoint
+ \ifdim\scratchdepth=\zeropoint\else
+ \hbox{\vrule\s!depth\scratchdepth\s!height\zeropoint\s!width\zeropoint}%
+ \fi
+ \else
+ \hbox{\vrule\s!depth\zeropoint\s!height\scratchheight\s!width\zeropoint}%
+ \fi
+ \ifdim\scratchwidth=\zeropoint\else
+ \ifx\MMLmspaceoption\v!test
+ \hbox to \scratchwidth{\showstruts\strut\hss\lower2\exheight\hbox{\infofont\xmlattdef{#1}{width}}\hss\strut}
+ \else
+ \hskip\scratchwidth
+ \fi
+ \fi
+ \else
+ \ifx\MMLmspaceoption\v!test
+ \hbox{\showstruts\strut\phantom{\triggermathstyle\normalmathstyle\mmlspacetext}\strut}
+ \else
+ \phantom{\triggermathstyle\normalmathstyle\mmlspacetext}
+ \fi
+ \fi
+ \endgroup
+\stopxmlsetups
+
+% later we can do a better job by manipulating node lists
+
+% \startxmlsetups mml:mline
+% % new, rather undefined, we need to capture a few keywords
+% \edef\mmllinewidth {\xmlatt{#1}{linethickness}}
+% \edef\mmllinetext {\xmlatt{#1}{spacing}}
+% \edef\mmllinelength{\xmlattdef{#1}{length}\!!zeropoint}
+% \ifx\mmllinewidth\empty
+% \!!deptha.5\linewidth
+% \else
+% \!!deptha.5\dimexpr\mmllinewidth\relax
+% \fi
+% \!!heighta\!!deptha
+% \ifx\mmllinetext\empty
+% \ifx\mmllinelength\empty
+% \!!widtha\zeropoint
+% \else
+% \!!widtha\mmllinelength
+% \fi
+% \else
+% \setbox\scratchbox\hbox{\mathematics{\mathstyle{\mmllinetext}}}% not ok
+% \!!widtha\wd\scratchbox
+% \fi
+% \hbox{\vrule\s!width\!!widtha\s!depth\!!deptha\s!height\!!heighta}
+% \stopxmlsetups
+
+\startxmlsetups mml:mglyph % probably never ok (hbox is needed in order to switch to normal font)
+ \begingroup
+ \edef\mmlglyphfontfamily{\xmlatt {#1}{fontfamily}}
+ \edef\mmlglyphalt {\xmlattdef{#1}{alt}{unknown}}
+ \edef\mmlglyphindex {\xmlatt {#1}{index}}
+ \ifx \mmlglyphfontfamily \empty
+ \hbox{\tttf[no fontfamily specified for \mmlglyphalt]}
+ \else\ifx\mmlglyphindex\empty
+ \hbox{\tttf[no index specified for \mmlglyphalt]}
+ \else
+ \hbox{\getglyph\mmlglyphfontfamily\mmlglyphindex}
+ \fi\fi
+ \endgroup
+\stopxmlsetups
+
+\startxmlsetups mml:maligngroup \stopxmlsetups % will be done when needed
+\startxmlsetups mml:malignmark \stopxmlsetups % will be done when needed
+
+\startxmlsetups mml:none \stopxmlsetups
+\startxmlsetups mml:mprescripts \stopxmlsetups
+
+\startxmlsetups mml:mmultiscripts
+ \ctxmodulemathml{mmultiscripts("#1")}
+\stopxmlsetups
+
+% goodie
+
+\definebuffer[mml]
+
+\def\stopmml{\xmlprocessbuffer{@mml@}{\thedefinedbuffer{mml}}{}}
+
+\stopmodule
+
+\protect \endinput
+
+% TODO:
+%
+% <apply><divide/>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% <apply><minus/>
+% <apply><minus/><ci>b</ci><ci>b</ci></apply>
+% <apply><minus/><ci>b</ci></apply>
+% <apply><root/> <ci>a</ci></apply>
+% </apply>
+% </apply>
+
+% \startmoduletestsection
+%
+% \def\xflushXMLstackwith#1#2#3#4% num bgroup egroup whatever
+% {\dostepwiserecurse{#1}\XMLstacklevel\plusone
+% {#2\relax
+% \ifnum\recurselevel>#1\relax#4\fi
+% \getXMLstackdata\recurselevel
+% #3}}
+%
+% \def\xflushXMLstackfrom#1#2#3%
+% {\dostepwiserecurse{#1}\XMLstacklevel\plusone
+% {#2\getXMLstackdata\recurselevel#3}}
+%
+% \startxmlsetups mml:minus
+% \doif \MMLsignreduction \v!yes {
+% \setMMLcreset{fn,\MMLcfunctionlist}
+% }
+% \ifcase\XMLstacklevel
+% \or
+% % self
+% \or
+% -\getXMLstackdata\plustwo
+% \else
+% \dostepwiserecurse \plustwo \XMLstacklevel \plusone {
+% \begingroup
+% \doifelse {\getXMLstackname\recurselevel} {apply} {
+% \ifnum\recurselevel=\plustwo
+% \begingroup
+% \dodoifelseMMCfunctioninapply \recurselevel {minus} {
+% \ifnum\XMLstacklevel>\plustwo
+% \endgroup
+% \else
+% \endgroup
+% \MMLcreset
+% \fi
+% } {
+% \endgroup
+% }
+% \else
+% \doifelseMMCfunctioninapply \recurselevel {\MMLcfunctionlist,\MMLcconstructlist} {
+% \MMLcreset
+% } {
+% }
+% \fi
+% } {
+% }
+% \getXMLstackdata\recurselevel
+% \ifnum\recurselevel<\XMLstacklevel\relax
+% -
+% \fi
+% \endgroup
+% }
+% \fi
+% \stopxmlsetups
+%
+% \stopmoduletestsection
diff --git a/tex/context/modules/mkiv/x-newmml.mkiv b/tex/context/modules/mkiv/x-newmml.mkiv
new file mode 100644
index 000000000..4c12daeee
--- /dev/null
+++ b/tex/context/modules/mkiv/x-newmml.mkiv
@@ -0,0 +1,16 @@
+%D \module
+%D [ file=x-newmml,
+%D version=2008.05.28,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=MathML Renderer,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\input x-mathml.mkiv
+
+\endinput
diff --git a/tex/context/modules/mkiv/x-pfs-01.mkiv b/tex/context/modules/mkiv/x-pfs-01.mkiv
new file mode 100644
index 000000000..8b06bd873
--- /dev/null
+++ b/tex/context/modules/mkiv/x-pfs-01.mkiv
@@ -0,0 +1,399 @@
+% pfsense status info, work in progress
+%
+% usage:
+%
+% context --environment=x-pfs-01 filename.xml
+%
+% or
+%
+% <?context-directive job ctxfile x-pfsense.ctx ?>
+
+\setupbodyfont
+ [dejavu,10pt]
+
+\setuplayout
+ [topspace=1cm,
+ backspace=1cm,
+ footer=0pt,
+ header=1cm,
+ width=middle,
+ height=middle]
+
+\setupheader
+ [style=bold]
+
+\setuphead
+ [section]
+ [style=\bfb]
+
+\setuphead
+ [subsection]
+ [style=\bfa]
+
+\setuppagenumbering
+ [location=]
+
+\dontcomplain
+
+% todo: show all values and map keys onto longer names via labels
+
+\startxmlsetups xml:system
+
+ \startsection[title={System}]
+
+ \startsubsection[title={Properties}]
+
+ \starttabulate[|B|T|]
+ \NC hostname \NC \xmlfirst{#1}{hostname} \NC \NR
+ \NC domain \NC \xmlfirst{#1}{domain} \NC \NR
+ \NC timezone \NC \xmlfirst{#1}{timezone} \NC \NR
+ \NC timeservers \NC \xmlfirst{#1}{timeservers} \NC \NR
+ \NC dnsserver \NC \xmlfirst{#1}{dnsserver} \NC \NR
+ \stoptabulate
+
+ \stopsubsection
+
+ \startsubsection[title={Groups}]
+ \xmlfilter{#1}{group/command(xml:system:group)}
+ \stopsubsection
+
+ \startsubsection[title={Users}]
+ \xmlfilter{#1}{user/command(xml:system:user)}
+ \stopsubsection
+
+ \stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:system:group
+
+ \starttabulate[|B|T|]
+ \NC name \NC \xmlfirst{#1}{/name} \NC \NR
+ \NC description \NC \xmlfirst{#1}{/descr} \NC \NR
+ \NC scope \NC \xmlfirst{#1}{/scope} \NC \NR
+ \NC gid \NC \xmlfirst{#1}{/gid} \NC \NR
+ \NC privilege \NC \xmlfirst{#1}{/priv} \NC \NR
+ \NC members \NC \xmlconcat{#1}{/member}{ } \NC \NR
+ \stoptabulate
+
+\stopxmlsetups
+
+\startxmlsetups xml:system:user
+
+ \starttabulate[|B|T|]
+ \NC name \NC \xmlfirst{#1}{/name} \NC \NR
+ \NC description \NC \xmlfirst{#1}{/descr} \NC \NR
+ \NC scope \NC \xmlfirst{#1}{/scope} \NC \NR
+ \NC uid \NC \xmlfirst{#1}{/uid} \NC \NR
+ \NC group \NC \xmlfirst{#1}{/groupname} \NC \NR
+ \NC privilege \NC \xmlfirst{#1}{/priv} \NC \NR
+ \NC password \NC \xmldoifelsetext{#1}{/password}{set}{unset} \NC \NR
+ \NC ipsec psk \NC \xmldoifelsetext{#1}{/ipsecpsk}{set}{unset} \NC \NR
+ \NC certificate \NC \xmldoifelsetext{#1}{/cert} {set}{unset} \NC \NR
+ \stoptabulate
+
+\stopxmlsetups
+
+\startxmlsetups xml:interfaces
+
+ \startsection[title={Interfaces}]
+
+ \xmlfilter{#1}{*/command(xml:interfaces:network)}
+
+ \stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:interfaces:network
+
+ \startsubsection[title={\xmltag{#1}}]
+
+ % <blockpriv/> <blockbogons/> <spoofmac/> <enable/>
+
+ \starttabulate[|B|T|]
+ \NC interface \NC \xmlfirst{#1}{/if} \NC \NR
+ \NC block private \NC \xmldoifelse{#1}{/blockpriv} {yes}{no} \NC \NR
+ \NC block bogons \NC \xmldoifelse{#1}{/blockbogons}{yes}{no} \NC \NR
+ \NC spoof mac address \NC \xmldoifelse{#1}{/spoofmac} {yes}{no} \NC \NR
+ \NC enable interface \NC \xmldoifelse{#1}{/enable} {yes}{no} \NC \NR
+ \NC ipaddress \NC \xmlfirst{#1}{/ipaddr} \NC \NR
+ \NC subnet \NC \xmlfirst{#1}{/subnet} \NC \NR
+ \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR
+ \NC description \NC \xmlfirst{#1}{/descr} \NC \NR
+ \stoptabulate
+
+ \stopsubsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:gateways
+
+ \startsection[title={Gateways}]
+
+ \xmlfilter{#1}{*/command(xml:gateways:entry)}
+
+ \stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:gateways:entry
+
+ \starttabulate[|B|T|]
+ \NC interface \NC \xmlfirst{#1}{/interface} \NC \NR
+ \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR
+ \NC name \NC \xmlfirst{#1}{/name} \NC \NR
+ \NC weight \NC \xmlfirst{#1}{/weight} \NC \NR
+ \NC interval \NC \xmlfirst{#1}{/interval} \NC \NR
+ \NC description \NC \xmlfirst{#1}{/descr} \NC \NR
+ \NC disable monitor \NC \xmlfirst{#1}{/monitor_disable} \NC \NR
+ \NC default gateway \NC \xmlfirst{#1}{/defaultgw} \NC \NR
+ \stoptabulate
+
+\stopxmlsetups
+
+\startxmlsetups xml:virtualips
+
+ \startsection[title={Virtual ipadresses}]
+
+ \xmlfilter{#1}{*/command(xml:virtualips:entry)}
+
+ \stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:virtualips:entry
+
+ \starttabulate[|B|T|]
+ \NC interface \NC \xmlfirst{#1}{/interface} \NC \NR
+ \NC type \NC \xmlfirst{#1}{/type} \NC \NR
+ \NC mode \NC \xmlfirst{#1}{/mode} \NC \NR
+ \NC subnet \NC \xmlfirst{#1}{/subnet}
+ /\xmlfirst{#1}{/subnet_bits} \NC \NR
+ \NC description \NC \xmlfirst{#1}{/descr} \NC \NR
+ \stoptabulate
+
+\stopxmlsetups
+
+\startxmlsetups xml:dhcp
+
+ \startsection[title={DHCP}]
+
+ \xmlfilter{#1}{*/command(xml:dhcp:network)}
+
+ \stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:dhcp:network
+
+ \startsubsection[title={\xmltag{#1}}]
+
+ \starttabulate[|B|T|]
+ \NC range \NC \xmlfirst{#1}{/range/from} \endash\ \xmlfirst{#1}{/range/to} \NC \NR
+ \NC domain \NC \xmlfirst{#1}{/domain} \NC \NR
+ \NC dnsserver \NC \xmlfirst{#1}{/dnsserver} \NC \NR
+ \NC gateway \NC \xmlfirst{#1}{/gateway} \NC \NR
+ \NC ddnsdomain \NC \xmlfirst{#1}{/ddnsdomain} \NC \NR
+ \stoptabulate
+
+ \xmldoif {#1} {/staticmap} {
+
+ \starttabulate[|T|T|T|p|]
+ \NC \rm\bf macaddress
+ \NC \rm\bf ipaddress
+ \NC \rm\bf hostname
+ \NC \rm\bf description
+ \NC \NR
+ \HL
+ \xmlfilter{#1}{/staticmap/command(xml:dhcp:network:entry)}
+ \stoptabulate
+
+ }
+
+ \stopsubsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:dhcp:network:entry
+
+ \NC \xmlfirst{#1}{/mac}
+ \NC \xmlfirst{#1}{/ipaddr}
+ \NC \xmlfirst{#1}{/hostname}
+ \NC \xmlfirst{#1}{/descr}
+ \NC \NR
+
+\stopxmlsetups
+
+\startxmlsetups xml:dnsmasq
+
+ \startsection[title={DNS MASQ}]
+
+ \starttabulate[|T|T|T|p|]
+ \NC \rm\bf host
+ \NC \rm\bf domain
+ \NC \rm\bf ipaddress
+ \NC \rm\bf description
+ \NC \NR
+ \HL
+ \xmlfilter{#1}{/hosts/command(xml:dnsmasq:hosts)}
+ \stoptabulate
+
+ \stopsection
+
+\stopxmlsetups
+
+
+\startxmlsetups xml:dnsmasq:hosts
+
+ \NC \xmlfirst{#1}{/host}
+ \NC \xmlfirst{#1}{/domain}
+ \NC \xmlfirst{#1}{/ip}
+ \NC \xmlfirst{#1}{/descr}
+ \NC \NR
+
+\stopxmlsetups
+
+\startxmlsetups xml:nat
+
+ \startsection[title={NAT}]
+
+ \startsubsection[title={Rules}]
+
+ \starttabulate[|T|T|T|T|T|p|]
+ \NC \rm\bf interface
+ \NC \rm\bf protocol
+ \NC \rm\bf source
+ \NC \rm\bf destination
+ \NC \rm\bf target
+ \NC \rm\bf description
+ \NC \NR
+ \HL
+ \xmlfilter{#1}{/rule/command(xml:nat:rule)}
+ \stoptabulate
+
+ \stopsubsection
+
+ \startsubsection[title={One to one}]
+
+ \starttabulate[|T|T|T|T|T|p|]
+ \NC \rm\bf interface
+ \NC \rm\bf protocol
+ \NC \rm\bf source
+ \NC \rm\bf destination
+ \NC \rm\bf external
+ \NC \rm\bf description
+ \NC \NR
+ \HL
+ \xmlfilter{#1}{/onetoone/command(xml:nat:onetoone)}
+ \stoptabulate
+
+ \stopsubsection
+
+\stopsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:nat:rule
+
+ \NC \xmlfilter{#1}{/interface/command(xml:checked)}
+ \NC \xmlfilter{#1}{/protocol/command(xml:checked)}
+ \NC \xmlfilter{#1}{/source/command(xml:checked)}
+ \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)}
+ :\xmlfilter{#1}{/destination/port/command(xml:checked)}
+ \NC \xmlfilter{#1}{/target/command(xml:checked)}
+ :\xmlfilter{#1}{/local-port/command(xml:checked)}
+ \NC \xmlfirst {#1}{/descr}
+ \NC \NR
+
+\stopxmlsetups
+
+\startxmlsetups xml:nat:onetoone
+
+ \NC \xmlfilter{#1}{/interface/command(xml:checked)}
+ \NC \xmlfilter{#1}{/protocol/command(xml:checked)}
+ \NC \xmlfilter{#1}{/source/command(xml:checked)}
+ \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)}
+ :\xmlfilter{#1}{/destination/port/command(xml:checked)}
+ \NC \xmlfilter{#1}{/external/command(xml:checked)}
+ :\xmlfilter{#1}{/local-port/command(xml:checked)}
+ \NC \xmlfirst {#1}{/descr}
+ \NC \NR
+
+\stopxmlsetups
+
+\startxmlsetups xml:checked
+ \xmldoifelse {#1} {/any} {
+ *
+ } {
+ \xmldoifelsetext {#1} {.} {
+ \xmlflush{#1}
+ } {
+ *
+ }
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:filter
+
+ \startsection[title={Filter}]
+
+ \startsubsection[title={Rules}]
+
+ \starttabulate[|T|T|T|T|T|p|]
+ \NC \rm\bf type
+ \NC \rm\bf interface
+ \NC \rm\bf protocol
+ \NC \rm\bf source
+ \NC \rm\bf destination
+ \NC \rm\bf description
+ \NC \NR
+ \HL
+ \xmlfilter{#1}{/rule/command(xml:filter:rule)}
+ \stoptabulate
+
+ \stopsubsection
+
+ \stopsubsection
+
+\stopxmlsetups
+
+\startxmlsetups xml:filter:rule
+
+ \NC \xmlfilter{#1}{/type/command(xml:checked)}
+ \NC \xmlfilter{#1}{/interface/command(xml:checked)}
+ \NC \xmlfilter{#1}{/protocol/command(xml:checked)}
+ \NC \xmlfilter{#1}{/source/(address|any)/command(xml:checked)}:
+ :\xmlfilter{#1}{/source/port/command(xml:checked)}
+ \NC \xmlfilter{#1}{/destination/(address|any)/command(xml:checked)}
+ :\xmlfilter{#1}{/destination/port/command(xml:checked)}
+ \NC \xmlfirst {#1}{/descr}
+ \NC \NR
+
+\stopxmlsetups
+
+\starttext
+
+ \doifelse {\inputfilename} {x-pfs-01.mkiv} {
+
+ \xmlloadonly{main}{router.xml}{}
+
+ \setupheadertexts[router.xml][\pagenumber]
+
+ } {
+
+ \xmlloadonly{main}{\inputfilename}{}
+
+ \setupheadertexts[\inputfilename][\pagenumber]
+
+ }
+
+ \xmlfilter{main}{/pfsense/system/command(xml:system)}
+ \xmlfilter{main}{/pfsense/interfaces/command(xml:interfaces)}
+ \xmlfilter{main}{/pfsense/gateways/command(xml:gateways)}
+ \xmlfilter{main}{/pfsense/virtualip/command(xml:virtualips)}
+ \xmlfilter{main}{/pfsense/dhcpd/command(xml:dhcp)}
+ \xmlfilter{main}{/pfsense/dnsmasq/command(xml:dnsmasq)}
+ \xmlfilter{main}{/pfsense/nat/command(xml:nat)}
+ \xmlfilter{main}{/pfsense/filter/command(xml:filter)}
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-pfsense.ctx b/tex/context/modules/mkiv/x-pfsense.ctx
new file mode 100644
index 000000000..8d7087cf2
--- /dev/null
+++ b/tex/context/modules/mkiv/x-pfsense.ctx
@@ -0,0 +1,15 @@
+<?xml version='1.0' standalone='yes'?>
+
+<!-- this is also a demo of using the xml interface -->
+
+<ctx:job>
+ <ctx:message>pfsense configuration listing</ctx:message>
+ <ctx:process>
+ <ctx:flags>
+ <ctx:flag>purge</ctx:flag>
+ </ctx:flags>
+ <ctx:resources>
+ <ctx:environment>x-pfs-01.mkiv</ctx:environment>
+ </ctx:resources>
+ </ctx:process>
+</ctx:job>
diff --git a/tex/context/modules/mkiv/x-physml.mkiv b/tex/context/modules/mkiv/x-physml.mkiv
new file mode 100644
index 000000000..dd9a164dd
--- /dev/null
+++ b/tex/context/modules/mkiv/x-physml.mkiv
@@ -0,0 +1,16 @@
+%D \module
+%D [ file=m-physml,
+%D version=2001.09.04,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=Loading PHYSML Filters,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo
+
+\endinput
diff --git a/tex/context/modules/mkiv/x-res-01.mkiv b/tex/context/modules/mkiv/x-res-01.mkiv
new file mode 100644
index 000000000..36070c615
--- /dev/null
+++ b/tex/context/modules/mkiv/x-res-01.mkiv
@@ -0,0 +1,427 @@
+%D \module
+%D [ file=x-fig-01,
+%D version=2001.03.21,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Figure Base Generation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D See \type {x-fig-00.tex} and \type {x-fig-04.tex} for more
+%D information on how to use and generate figure databases.
+%D This file loads the file named \type {\jobfilename}
+%D (\TEXEXEC\ will set this variable). You can apply this
+%D style to a database by saying:
+%D
+%D \starttyping
+%D context --input=d-res-01.xml auto:x-res-01.mkiv
+%D \stoptyping
+%D
+%D The following modes are supported (not all yet in mkiv):
+%D
+%D \starttabulate[|lT|l|]
+%D \NC letter \NC map the preview on letter size \NC \NR
+%D \NC compact \NC use an alternative presentation \NC \NR
+%D \NC clipgrid-distance \NC add a copy with grid overlayed \NC \NR
+%D \NC clipgrid-steps \NC add a copy with grid overlayed \NC \NR
+%D \NC previewpage-A4 \NC show graphic relative to A4 \NC \NR
+%D \NC previewpage-letter \NC show graphic relative to letter \NC \NR
+%D \NC previewpage-S6 \NC show graphic relative to S6 \NC \NR
+%D \stoptabulate
+%D
+%D The resulting file has the following characteristics:
+%D
+%D \startitemize[packed]
+%D \startitem the document is split into three sections: first each
+%D figure is shown at its own page, then an overview of figures is
+%D shown with some data alongside, and finally an index and table of
+%D contents shows up \stopitem
+%D \startitem there is no title page, which means that one can access
+%D a figure by page number without offset \stopitem
+%D \startitem the document is opened at the first overview page, that
+%D is, when the viewer supports it \stopitem
+%D \startitem the graphic is shown 3~times: on a page of its own,
+%D scaled to a fixed dimension, and relative to a4 or letter paper
+%D size \stopitem
+%D \startitem the labels can be accessed in an index and list at the
+%D end of the document \stopitem
+%D \stopitemize
+
+\defineregister
+ [figureindex]
+
+\setupregister
+ [figureindex]
+ [criterium=text,
+ interaction=text,
+ pagenumber=no,
+ indicator=no]
+
+\setuptolerance
+ [verytolerant]
+
+\setupbuttons
+ [offset=10pt,
+ width=broad,
+ strut=no,
+ rulethickness=1pt,
+ framecolor=darkred]
+
+\setuplayout
+ [topspace=15pt,
+ backspace=15pt,
+ header=0pt,
+ footer=0pt,
+ bottom=20pt,
+ bottomdistance=10pt,
+ width=middle,
+ height=fit]
+
+\setupbackgrounds
+ [page]
+ [background=,
+ backgroundcolor=gray]
+
+\setupinteractionscreen
+ [width=max,
+ height=max]
+
+\setupinteraction
+ [style=,
+ color=,
+ contrastcolor=,
+ state=start]
+
+\setuphead
+ [section]
+ [style=bfb]
+
+\setupinteractionmenu
+ [bottom]
+ [left=\hfill,
+ middle=\hskip10pt,
+ frame=off,
+ style=bold,
+ background=color,
+ backgroundcolor=darkred,
+ foregroundcolor=white]
+
+\startinteractionmenu[bottom]
+ \but [begin] begin \\
+ \but [index] index \\
+ \but [list] list \\
+ \but [CloseDocument] close \\
+ \but [PreviousJump] go back \\
+\stopinteractionmenu
+
+\setupinteraction
+ [openaction=begin]
+
+\setuppapersize
+ [S6][S6]
+
+\setupbackgrounds
+ [page]
+ [background=color]
+
+\setupinteraction
+ [menu=on]
+
+\setupbodyfont
+ [tt,10pt]
+
+\definesymbol [attachment] [{\strut\bf\color[darkred]{\inputfilename}}] % jobname.xml}}]
+\setupattachments [symbol=attachment,alternative=,location=text]
+\useattachment [datafile] [\inputfilename]
+
+\xmlloadonly{main}{\inputfilename}{}
+
+\mainlanguage[\xmlattributedef{main}{/rlx:library}{language}{en}]
+
+\startxmlsetups xml:resource:asis
+ \startTEXpage[pagestate=start]
+ \xmldoifelsetext{#1}{/rlx:label} {
+ \edef\CurrentLabel{\xmltext{#1}{rlx:label}}
+ } {
+ \edef\CurrentLabel{\xmltext{#1}{rlx:file}}
+ }
+ \pagereference [
+ asis:\CurrentLabel
+ ]
+ \gotobox {
+ \externalfigure[\xmltext{#1}{/rlx:file}]
+ }[% tricky no space before [
+ data:\CurrentLabel
+ ]
+ \stopTEXpage
+\stopxmlsetups
+
+\definemeasure[figure:width] [210mm]
+\definemeasure[figure:height][297mm]
+
+\startmode[letter]
+ \enablemode[previewpage-letter]
+\stopmode
+
+\startmode[previewpage-A4]
+ \definemeasure[figure:width] [210mm]
+ \definemeasure[figure:height][297mm]
+\stopmode
+
+\startmode[previewpage-letter]
+ \definemeasure[figure:width] [8.5in]
+ \definemeasure[figure:height][11in]
+\stopmode
+
+\startmode[previewpage-S6]
+ \definemeasure[figure:width] [600pt]
+ \definemeasure[figure:height][450pt]
+\stopmode
+
+\startxmlsetups xml:resource:a
+ \button
+ [
+ width=150pt,
+ height=100pt,
+ offset=10pt,
+ frame=off,
+ background=color,
+ backgroundcolor=white,
+ color=
+ ]
+ {
+ \externalfigure
+ [\xmltext{#1}{rlx:file}]
+ [factor=max]
+ }
+ [
+ grid:\CurrentLabel
+ ]
+\stopxmlsetups
+
+\startxmlsetups xml:resource:b
+ \framed
+ [
+ width=150pt,
+ height=100pt,
+ offset=10pt,
+ frame=off,
+ background=color,
+ backgroundcolor=white,
+ color=
+ ]
+ {
+ \externalfigure [
+ \xmltext{#1}{rlx:file}
+ ] [
+ factor=max
+ ]
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:resource:data
+
+ % using a layer makes more sense but we had this ...
+
+ \xmldoifelsetext{#1}{/rlx:label} {
+ \edef\CurrentLabel{\xmltext{#1}{rlx:label}}
+ } {
+ \edef\CurrentLabel{\xmltext{#1}{rlx:file}}
+ }
+
+ \button {
+ \hbox to \hsize {
+ \forgetall
+ \dontcomplain
+ \pagereference[data:\CurrentLabel]
+
+ %\ifnum\CurrentPage=1 \pagereference[begin]\fi
+
+ \expanded{\figureindex{\xmltext{#1}{/rlx:label}}}
+
+ \vbox to 100pt {
+ \hsize30pt
+ \vskip5pt
+ \hbox to \hsize {
+ \hss
+ \strut
+ \bf
+ \at[asis:\CurrentLabel]
+ \hss
+ }
+ \vfill
+ }
+ \advance\hsize by -30pt
+ \doifelsemode {clipgrid-distance,clipgrid-steps} {
+ \xmlsetup{#1}{xml:resource:a}
+ } {
+ \xmlsetup{#1}{xml:resource:b}
+ }
+ \edef\CurrentWidth {\the\dimexpr\figurenaturalwidth}
+ \edef\CurrentHeight{\the\dimexpr\figurenaturalheight}
+ \advance\hsize by -150pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt {
+ \hsize40pt
+ \framed [
+ offset=overlay,
+ framecolor=darkred,
+ rulethickness=.5pt
+ ] {
+ \scale [
+ width=40pt
+ ] {
+ \framed [
+ width=\measure{figure:width},
+ height=\measure{figure:height},
+ offset=overlay,
+ frame=off,
+ background=color,
+ backgroundcolor=white
+ ] {
+ \externalfigure
+ [
+ \xmltext{#1}{rlx:file}
+ ] [
+ reset=yes
+ ]
+ }
+ }
+ }
+ \vfill
+ }
+ \advance\hsize by -40pt
+ \hskip10pt
+ \advance\hsize by -10pt
+ \vbox to 100pt {
+ \blank[disable]
+ \starttabulate[|Bel|p|]
+ \NC file \NC \xmltext{#1}{/rlx:file} \NC \NR
+ \xmldoif{#1}{/rlx:label} {\NC label \NC \xmltext{#1}{/rlx:label} \NC \NR}
+ \NC dimensions \NC \CurrentWidth\ * \CurrentHeight \NC \NR
+ \xmldoif{#1}{/rlx:copyright} {\NC copyright \NC \xmltext{#1}{/rlx:copyright} \NC \NR}
+ \xmldoif{#1}{/rlx:status} {\NC status \NC \xmltext{#1}{/rlx:status} \NC \NR}
+ \xmldoif{#1}{/rlx:comment} {\NC comment \NC \xmltext{#1}{/rlx:comment} \NC \NR}
+ \stoptabulate
+ \vfill
+ }
+ }
+ } [
+ asis:\CurrentLabel
+ ]
+
+ \vskip10pt
+
+\stopxmlsetups
+
+\startxmlsetups xml:description
+
+ \starttabulate[|lBe|p|]
+ \xmldoif{#1}{/rlx:organization} {\NC organization \NC \xmltext{#1}{/rlx:organization} \NC \NR}
+ \xmldoif{#1}{/rlx:project} {\NC project \NC \xmltext{#1}{/rlx:project} \NC \NR}
+ \xmldoif{#1}{/rlx:product} {\NC product \NC \xmltext{#1}{/rlx:product} \NC \NR}
+ \xmldoif{#1}{/rlx:comment} {\NC comment \NC \xmltext{#1}{/rlx:comment} \NC \NR}
+ \NC specification \NC \attachment[datafile] \NC \NR
+ \stoptabulate
+
+\stopxmlsetups
+
+\starttext
+
+ \xmlfilter{main}{/rlx:library/rlx:resource/command(xml:resource:asis)}
+
+ \subject {Figure collection}
+
+ \xmlfilter{main}{/rlx:library/rlx:description/command(xml:description)}
+
+ \subject [list] {List of figures}
+
+ \xmlfilter{main}{/rlx:library/rlx:resource/command(xml:resource:data)}
+
+ \page
+
+ \subject [index] {Index of figures}
+
+ \startcolumns
+ \placeregister[figureindex]
+ \stopcolumns
+
+\stoptext
+
+% \doifmodeelse{clipgrid-distance,clipgrid-steps}{\page}{\stoptext}
+
+% \startuniqueMPgraphic{clipgrid}{dx,dy,nx,ny,type}
+% numeric gdx, gdy, lbx, lby ;
+% if \MPvar{type}=1 :
+% gdx := \MPvar{dy} ;
+% gdy := \MPvar{dx} ;
+% else :
+% gdx := OverlayWidth /\MPvar{nx} ;
+% gdy := OverlayHeight/\MPvar{ny} ;
+% fi ;
+% lbx := gdx ;
+% lby := gdy ;
+% defaultfont := "\truefontname{Mono}" ;
+% defaultscale := .5 ;
+% numeric pen ; pen := .25pt ;
+% def MyGrid text t =
+% draw vlingrid (0,OverlayWidth ,gdy,OverlayWidth ,OverlayHeight) t ;
+% draw hlingrid (0,OverlayHeight,gdx,OverlayHeight,OverlayWidth ) t ;
+% enddef ;
+% pickup pencircle scaled pen ;
+% MyGrid withcolor white ;
+% MyGrid dashed evenly scaled pen ;
+% draw OverlayBox withcolor white ;
+% draw OverlayBox dashed evenly scaled pen ;
+% draw vlinlabel.bot(0,eps+OverlayWidth /lby,2,OverlayWidth ) ;
+% draw hlinlabel.lft(0,eps+OverlayHeight/lbx,2,OverlayHeight) ;
+% setbounds currentpicture to OverlayBox enlarged (2*EmWidth) ;
+% \stopuniqueMPgraphic
+
+% \presetMPvariable[clipgrid][dx=10pt]
+% \presetMPvariable[clipgrid][dy=10pt]
+% \presetMPvariable[clipgrid][nx=10]
+% \presetMPvariable[clipgrid][ny=10]
+
+% \startmode[clipgrid-distance]
+% \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=1}]
+% \stopmode
+
+% \startmode[clipgrid-steps]
+% \defineoverlay[grid][\uniqueMPgraphic{clipgrid}{type=2}]
+% \stopmode
+
+% \setupexternalfigures
+% [background={color,foreground,grid},
+% backgroundcolor=white]
+
+% \def\StartFigureD
+% {\StartFigureA}
+
+% \def\StopFigureD
+% {\doglobal\increment\CurrentPage
+% \setupbackgrounds[page][background=page]
+% \startpagefigure[\XMLflush{rlx:file}][offset=20pt]%
+% \doifelsenothing{\XMLflush{rlx:label}}
+% {\expanded{\definereference[Description][about:\XMLflush{rlx:file}]}%
+% \expanded{\pagereference[grid:\XMLflush{rlx:file}]}}
+% {\expanded{\definereference[Description][about:\XMLflush{rlx:label}]}%
+% \expanded{\pagereference[grid:\XMLflush{rlx:label}]}}
+% \stoppagefigure
+% %\pagefigure[\XMLflush{rlx:file}][offset=20pt]
+% \setupbackgrounds[page][background=]
+% \egroup}
+
+% \defineXMLignore [rlx:description]
+% \defineXMLenvironment [rlx:figure] \StartFigureD \StopFigureD
+
+% \doglobal\newcounter\CurrentPage
+
+% \processXMLfilegrouped{\jobfullname} \page
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-res-50.mkiv b/tex/context/modules/mkiv/x-res-50.mkiv
new file mode 100644
index 000000000..62a86b7a7
--- /dev/null
+++ b/tex/context/modules/mkiv/x-res-50.mkiv
@@ -0,0 +1,431 @@
+%D \module
+%D [ file=x-res-50,
+%D version=2004.02.18,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Multimedia Presentation,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The xml mapping has to be redone!
+
+\endinput
+
+%D This is a preliminary module, using a preliminary xml media format that
+%D looks as follows (record is embedded in resource library element):
+%D
+%D \starttyping
+%D <rl:mediaclip label="sample 1">
+%D <rl:name>Sample One</rl:name>
+%D <rl:mime>application/x-shockwave-flash</rl:mime>
+%D <rl:file>http://localhost/mb.swf</rl:file>
+%D <rl:width>8cm</rl:width>
+%D <rl:height>6cm</rl:height>
+%D <rl:text>Nothing special to be said.</rl:text>
+%D <rl:picture>cow.pdf</rl:picture>
+%D </rl:mediaclip>
+%D
+%D <rl:mediaclip label="sample 2">
+%D <rl:name>Sample Two</rl:name>
+%D <rl:mime>audio/mpeg</rl:mime>
+%D <rl:file>mb.mp3</rl:file>
+%D <rl:picture>mb.jpg</rl:picture>
+%D </rl:mediaclip>
+%D \stoptyping
+%D
+%D \starttyping
+%D texexec --pdf --use=med-show yourfile.xml
+%D \stoptyping
+%D
+%D Bonus:
+%D
+%D \starttyping
+%D --arg="url=http://localhost:8881/e:/media"
+%D \stoptyping
+
+% output=pdftex
+
+% \nopdfcompression
+
+% bugs in recognizing embedded stream cq. player
+% bugs in layers + hide/vide
+% bugs in save javascripts
+% bugs all over the place
+
+% in principe kan menu overal hetzelfde zijn als we via JS per pagina de clip var zetten,
+% hoewel, misschien zal het menu gaan afhangen van de soort clip
+
+% viewerlayer (eigenschap) aan framed en layer
+
+\usemodule[meta-dum] \usemodule[contml] \autoXMLnamespace [context]
+
+\doifelsevariable{environment}{url}
+ {\setvariables[mediaclip][url=\getvariable{environment}{url}/]}
+ {\setvariables[mediaclip][url=]}
+
+\startmode [silent]
+
+ \setvariables[mediaclip:option][start=]
+
+\stopmode
+
+\startnotmode [silent]
+
+ \setvariables[mediaclip:option][start=auto]
+
+\stopnotmode
+
+\chardef\XMLtokensreduction=1 \dontcomplain % \showframe \pdfcompresslevel=0
+
+\setuppapersize
+ [S6][S6]
+
+\definemeasure [GapSize] [\dimexpr( 15pt)]
+\definemeasure [EdgeWidth] [\dimexpr(100pt)]
+\definemeasure [TextWidth] [\dimexpr(.5\textwidth)]
+\definemeasure [RenderingWidth] [\dimexpr(\textwidth)]
+\definemeasure [RenderingHeight] [\dimexpr(\textheight)]
+
+% \XMLflush{rl:ratio}\dimexpr(.75\textwidth),
+
+\setuplayout
+ [backspace=\measure{GapSize},
+ topspace=\measure{GapSize},
+ header=0pt,
+ footer=0pt,
+ margin=0pt,
+ edgedistance=2\measure{GapSize},
+ rightedge=\measure{EdgeWidth},
+ bottomdistance=2\measure{GapSize},
+ bottom=2\measure{GapSize},
+ height=fit,
+ width=fit]
+
+\setupinteraction
+ [state=start,
+ color=lightgray,
+ contrastcolor=lightgray,
+ openaction=PresetFields,
+ closeaction=ForgetChanges,
+ menu=on,
+ click=no]
+
+\setupinteractionscreen
+ [option=max]
+
+\setupcolors
+ [state=start]
+
+\usetypescript
+ [palatino][texnansi]
+
+\setupbodyfont
+ [palatino]
+
+\definecolor[darkgray] [s=.2]
+\definecolor[mediumgray][s=.5]
+\definecolor[lightgray] [s=.8]
+\definecolor[transgray] [s=1,t=.9,a=1]
+
+\setupbackgrounds
+ [page]
+ [backgroundoffset=\measure{GapSize},
+ background={color,pagebutton},
+ backgroundcolor=black]
+
+\definelayer
+ [main]
+ [width=\textwidth,
+ height=\textheight]
+
+\definelayer
+ [extra]
+ [width=\rightedgewidth,
+ height=\bottomheight]
+
+\setupbackgrounds
+ [text]
+ [backgroundoffset=0pt,
+ background=main]
+
+\setupbackgrounds
+ [bottom][rightedge]
+ [backgroundoffset=0pt,
+ background=extra]
+
+% java scripts
+
+\startJSpreamble {handy} used now
+
+ function ForgetChanges ()
+ { this.dirty = false }
+
+ function PresetFields ()
+ { this.syncAnnotScan() }
+
+\stopJSpreamble
+
+\definereference[PresetFields] [JS(PresetFields)]
+\definereference[ForgetChanges][JS(ForgetChanges)]
+
+% layers
+
+\defineviewerlayer [menulayer] [title=menulayer]
+\defineviewerlayer [textlayer] [title=textlayer,state=stop]
+\defineviewerlayer [datalayer] [title=datalayer,state=stop]
+
+\setupfield
+ [rollbutton]
+ [fieldlayer=menulayer]
+
+\setupfield
+ [rollbutton]
+ [option=auto]
+
+\definepalet
+ [rollover]
+ [n=darkgray,
+ r=lightgray,
+ d=darkgray]
+
+% list
+
+\definelist
+ [clips]
+ [expansion=yes,
+ criterium=text,
+ alternative=f]
+
+% navigation
+
+\defineoverlay[pagebutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer},ToggleLayer{menulayer}}]
+\defineoverlay[textbutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}]
+\defineoverlay[databutton][\overlaybutton{HideLayer{textlayer},HideLayer{datalayer}}]
+
+% clips
+
+\defineXMLenvironment
+ [rl:mediaclip]
+ {\setups[mediaclip:start]}
+ {\setups[mediaclip:stop]}
+
+\newcounter\MediaClip
+
+\startsetups[mediaclip:start]
+
+ \bgroup \startXMLignore
+
+ % no \startstandardmakeup here since we need the dsta in the menuconstruction
+
+ \defineXMLsave [rl:name]
+ \defineXMLsave [rl:visualization]
+ \defineXMLsave [rl:file]
+ \defineXMLsave [rl:mime]
+ \defineXMLsave [rl:picture] [backgroundcolor=lightgray]
+
+ \defineXMLsavecontent [rl:text] {No additional info.}
+ \defineXMLsavecontent [rl:width] {\measure{RenderingWidth}}
+ \defineXMLsavecontent [rl:height] {\measure{RenderingHeight}}
+ \defineXMLsavecontent [rl:aspect] {1}
+
+\stopsetups
+
+\startsetups[mediaclip:stop]
+
+ \startstandardmakeup
+
+ \doifXMLdataelse{rl:file}
+ {\setups[mediaclip:file:yes]}
+ {}
+
+ \doifXMLdataelse{rl:picture}
+ {\doifelse{\XMLflush{rl:picture}}{self}
+ {\setups[mediaclip:picture:self]}
+ {\setups[mediaclip:picture:yes]}}
+ {\setups[mediaclip:picture:no]}
+
+ \doifXMLdata{rl:text}
+ {\setups[mediaclip:text]}
+
+ \setlayerframed
+ [extra]
+ [preset=rightbottom]
+ [frame=off,offset=overlay,width=fit,background=databutton,align=left]
+ {\startviewerlayer[datalayer]\setups[mediaclip:data]\stopviewerlayer}
+
+ \doifXMLdataelse{rl:name}
+ {\writetolist[clips]{}{\XMLflush{rl:name}}}
+ {\writetolist[clips]{}{\XMLpar{rl:mediaclip}{label}{unknown}}}
+
+ \stopstandardmakeup
+
+ \stopXMLignore \egroup
+
+\stopsetups
+
+\setuptabulate
+ [before=,
+ after=]
+
+\def\rlCleanupFileName#1%
+ {\bgroup
+ \def\cleanup##1##2{\ifnum##1##2=20 \space\else\char\octnumber{##1##2}\fi}%
+ \defineactivecharacter 37 {\cleanup}%
+ \scantokens{#1}%
+ \egroup}
+
+\startsetups[mediaclip:data]
+
+ \noindent \buttonframed
+ [framecolor=lightgray,
+ foregroundcolor=lightgray]
+ {\bf\expanded{\rlCleanupFileName{\XMLflush{rl:file}}}}
+
+ \vskip.75\measure{GapSize}
+
+ \noindent \buttonframed
+ [framecolor=lightgray,
+ foregroundcolor=lightgray]
+ {\bf\XMLflush{rl:mime}}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:self]
+
+ \definerenderingwindow
+ [mediaclip]
+ [width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height},
+ frame=off,
+ openpageaction=StartCurrentRendering,
+ closepageaction=StopCurrentRendering]
+
+ \setlayer
+ [main]
+ {\placerenderingwindow[mediaclip][mediaclip-\MediaClip]}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:yes]
+
+ \setlayer
+ [main]
+ {\externalfigure
+ [\XMLflush{rl:picture}]
+ [background=color,
+ backgroundcolor=\XMLpar{rl:picture}{backgroundcolor}{lightgray},
+ factor=max,
+ width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height}]}
+
+\stopsetups
+
+\startsetups[mediaclip:picture:no]
+
+ \setlayer
+ [main]
+ {\externalfigure
+ [dummy]
+ [width=\XMLflush{rl:width},
+ height=\XMLflush{rl:height}]}
+
+\stopsetups
+
+\startsetups[mediaclip:file:yes]
+
+ \doglobal\increment\MediaClip
+
+ \useexternalrendering
+ [mediaclip-\MediaClip]
+ [\XMLflush{rl:mime}]
+ [\getvariable{mediaclip}{url}\XMLflush{rl:file}]
+ [\getvariable{mediaclip:option}{start}]
+
+\stopsetups
+
+\defineinteractionmenu
+ [navigation] [right]
+
+\defineinteractionmenu
+ [control] [bottom]
+
+\setupinteractionmenu
+ [navigation,control]
+ [state=start,
+ frame=on,
+ middle=\hskip.5\measure{GapSize},
+ inbetween=\vskip.5\measure{GapSize}]
+
+\setupinteractionmenu
+ [right,bottom]
+ [distance=overlay]
+
+\startinteractionmenu [navigation]
+ \rob [HideLayer{textlayer},FirstPage] First Page \\
+ \rob [HideLayer{textlayer},PreviousPage] Previous Page \\
+ \rob [HideLayer{textlayer},NextPage] Next Page \\
+ \rob [HideLayer{textlayer},LastPage] Last Page \\
+ \rob [HideLayer{textlayer},clips] List Of Clips \\
+ \rob [ForgetChanges,CloseDocument] Close Document \\
+\stopinteractionmenu
+
+\startinteractionmenu [control]
+ \rob [StartRendering{mediaclip-\MediaClip}] Start \\
+ \rob [StopRendering{mediaclip-\MediaClip}] Stop \\
+ \rob [PauseRendering{mediaclip-\MediaClip}] Pause \\
+ \rob [ResumeRendering{mediaclip-\MediaClip}] Resume \\
+ \rob [ToggleLayer{datalayer}] Info \\
+ \doifXMLdata{rl:text}{\rob [HideLayer{datalayer},ToggleLayer{textlayer}] Text \\}
+\stopinteractionmenu
+
+\startsetups[mediaclip:text]
+
+ \setlayer
+ [extra]
+ [preset=rightbottom]
+ {\startviewerlayer[textlayer]
+ \framed
+ [align=normal,
+ frame=off,
+ width=\measure{TextWidth},
+ foregroundcolor=darkgray,
+ background={color,textbutton},
+ backgroundcolor=lightgray]
+ {\XMLflush{rl:text}}
+ \stopviewerlayer}
+
+\stopsetups
+
+\setupcolors[textcolor=lightgray]
+
+\startsetups [library:start]
+
+ \starttext
+
+ \setupinteractionmenu[control][state=stop]
+
+ \title[clips]{List of Media Clips}
+
+ \placelist[clips] \page
+
+ \setupinteractionmenu[control][state=start]
+
+\stopsetups
+
+\startsetups [library:stop]
+
+ \stoptext
+
+\stopsetups
+
+\defineXMLenvironment [rl:resourcelibrary]
+ {\setups[library:start]}
+ {\setups[library:stop]}
+
+\doifelsenothing{\inputfilename}
+ {\processXMLfile{mediaclient.xml}}
+ {\processXMLfile{\inputfilename}}
diff --git a/tex/context/modules/mkiv/x-set-11.mkiv b/tex/context/modules/mkiv/x-set-11.mkiv
new file mode 100644
index 000000000..c82b9735d
--- /dev/null
+++ b/tex/context/modules/mkiv/x-set-11.mkiv
@@ -0,0 +1,859 @@
+%D \module
+%D [ file=x-set-11,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Definitions,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% we can make this module a bit cleaner using more recent features
+% like sorting the xml directly
+
+% \startluacode
+% collectgarbage("stop")
+% function collectgarbage() return 0 end
+% \stopluacode
+
+% todo: for fun: pure lua interface, but as this style evolved over 15 years
+% it's a waste of time
+%
+% todo:
+%
+% \setup{setupinterlinespace}
+% \setup{setupinterlinespace:1}
+% \setup{setupinterlinespace:2}
+%
+% cd:include -> filename
+% cd:choice
+%
+% register, interaction
+
+\startmessages dutch library: setup
+ title: setup
+ formula: formule
+ number: getal
+ list: lijst
+ dimension: maat
+ mark: markering
+ reference: verwijzing
+ command: commando
+ file: file
+ name: naam
+ identifier: naam
+ text: tekst
+ section: sectie
+ singular: naam enkelvoud
+ plural: naam meervoud
+ matrix: n*m
+ see: zie
+ inherits: erft van
+ 1: de karakters < en > zijn globaal actief!
+ 2: -- wordt verwerkt
+ 3: -- is niet gedefinieerd
+ 4: -- wordt nogmaals verwerkt
+ optional: opt
+ displaymath: formule
+ index: ingang
+ math: formule
+ nothing: leeg
+ file: file
+ position: positie
+ reference: verwijzing
+ csname: naam
+ destination: bestemming
+ triplet: triplet
+ word: woord
+ content: tekst
+\stopmessages
+
+\startmessages english library: setup
+ title: setup
+ formula: formula
+ number: number
+ list: list
+ dimension: dimension
+ mark: mark
+ reference: reference
+ command: command
+ file: file
+ name: name
+ identifier: identifier
+ text: text
+ section: section
+ singular: singular name
+ plural: plural name
+ matrix: n*m
+ see: see
+ inherits: inherits from
+ 1: the characters < and > are globally active!
+ 2: -- is processed
+ 3: -- is undefined
+ 4: -- is processed again
+ optional: opt
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages german library: setup
+ title: Setup
+ formula: Formel
+ number: Nummer
+ list: Liste
+ dimension: Dimension
+ mark: Beschriftung
+ reference: Referenz
+ command: Befehl
+ file: Datei
+ name: Name
+ identifier: Name
+ text: Text
+ section: Abschnitt
+ singular: singular
+ plural: plural
+ matrix: n*m
+ see: siehe
+ inherits: inherits from
+ 1: Die Zeichen < und > gelten global!
+ 2: -- wird verarbeitet
+ 3: -- ist undefiniert
+ 4: -- ist mehrmals verarbeitet
+ optional: opt
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages czech library: setup
+ title: setup
+ formula: rovnice
+ number: cislo
+ list: seznam
+ dimension: dimenze
+ mark: znacka
+ reference: reference
+ command: prikaz
+ file: soubor
+ name: jmeno
+ identifier: jmeno
+ text: text
+ section: sekce
+ singular: jmeno v singularu
+ plural: jmeno v pluralu
+ matrix: n*m
+ see: viz
+ inherits: inherits from
+ 1: znaky < a > jsou globalne aktivni!
+ 2: -- je zpracovano
+ 3: -- je nedefinovano
+ 4: -- je zpracovano znovu
+ optional: opt
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages italian library: setup
+ title: setup
+ formula: formula
+ number: number
+ list: list
+ dimension: dimension
+ mark: mark
+ reference: reference
+ command: command
+ file: file
+ name: name
+ identifier: name
+ text: text
+ section: section
+ singular: singular name
+ plural: plural name
+ matrix: n*m
+ see: see
+ inherits: inherits from
+ 1: the characters < and > are globally active!
+ 2: -- is processed
+ 3: -- is undefined
+ 4: -- is processed again
+ optional: opt
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages romanian library: setup
+ title: setari
+ formula: formula
+ number: numar
+ list: lista
+ dimension: dimensiune
+ mark: marcaj
+ reference: referinta
+ command: comanda
+ file: fisier
+ name: nume
+ identifier: nume
+ text: text
+ section: sectiune
+ singular: nume singular
+ plural: nume pluram
+ matrix: n*m
+ see: vezi
+ inherits: inherits from
+ 1: caracterele < si > sunt active global!
+ 2: este procesat --
+ 3: -- este nedefinit
+ 4: -- este procesat din nou
+ optional: opt
+ displaymath: formula
+ index: entry
+ math: formula
+ nothing: empty
+ file: file
+ position: position
+ reference: reference
+ csname: name
+ destination: destination
+ triplet: triplet
+ word: word
+ content: text
+\stopmessages
+
+\startmessages french library: setup
+ title: réglage
+ formula: formule
+ number: numéro
+ list: liste
+ dimension: dimension
+ mark: marquage
+ reference: reference
+ command: commande
+ file: fichier
+ name: nom
+ identifier: identificateur
+ text: texte
+ section: section
+ singular: nom singulier
+ plural: nom pluriel
+ matrix: n*m
+ see: vois
+ inherits: herite de
+ 1: les caractères < et > sont globalement actifs !
+ 2: -- est traité
+ 3: -- n'est pas défini
+ 4: -- est traité de nouveau
+ optional: opt
+ displaymath: formule
+ index: entrée
+ math: formule
+ nothing: vide
+ file: fichier
+ position: position
+ reference: réference
+ csname: nom
+ destination: destination
+ triplet: triplet
+ word: mot
+ content: texte
+\stopmessages
+
+\unprotect
+
+% general
+
+\unexpanded\def\setupnumfont {}
+\unexpanded\def\setuptxtfont {}
+\unexpanded\def\setupintfont {\WORD}
+\unexpanded\def\setupvarfont {\sl}
+\unexpanded\def\setupoptfont {\sl}
+\unexpanded\def\setupalwcolor{}
+\unexpanded\def\setupoptcolor{darkgray}
+
+\def\c!setup!definereserved#1#2%
+ {\setvalue{c!setup!:r:#1}{#2}}
+
+\def\c!setup!reserved!#1%
+ {\executeifdefined{c!setup!:r:#1}{#1}}
+
+\def\c!setup!internal!#1%
+ {\dontleavehmode
+ \begingroup
+ \setupintfont{#1}%
+ \endgroup}
+
+\def\c!setup!text!#1%
+ {\dontleavehmode
+ \begingroup
+ \setupvarfont{#1}%
+ \endgroup}
+
+\def\c!setup!command!#1%
+ {{\setupvarfont{\texescape...#1}}}
+
+\def\??stp{@@stp}
+
+\defineregister
+ [texmacro]
+% [texmacros]
+
+\definesorting
+ [texcommand]
+% [texcommands]
+
+\setupsorting
+ [texcommand]
+ [\c!command=\showsetupinlist,
+ \c!criterium=\@@stpcriterium]
+
+\pushmacro\setuptext
+
+\defineframedtext
+ [setuptext]
+ [\c!width=\hsize,
+ \c!height=\v!fit,
+ \c!align=\v!right,
+ \c!offset=0.75em]
+
+\popmacro\setuptext
+
+%D Loading:
+
+\let\currentSETUPfullname\s!unknown
+
+\startxmlsetups xml:setups:assemblename
+ \doifelse {\xmlatt{#1}{type}} {environment} {
+ \let\currentSETUPprefix\e!start
+ } {
+ \let\currentSETUPprefix\empty
+ }
+ % \edef\currentSETUPname{\xmlatt{#1}{name}}
+ \edef\currentSETUPname{\xmlattribute{#1}{/sequence/string[1]}{value}}%
+ \doifelse {\xmlatt{#1}{generated}} {yes} {
+ \def\currentSETUPgenerated{*}
+ } {
+ \let\currentSETUPgenerated\empty
+ }
+ \doifelsenothing {\xmlatt{#1}{variant}} {
+ \let\currentSETUPvariant\empty
+ } {
+ \def\currentSETUPvariant{:\xmlatt{#1}{variant}}
+ }
+ \edef\currentSETUPfullname {
+ \currentSETUPprefix
+ \currentSETUPname
+ \currentSETUPvariant
+ \currentSETUPgenerated
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:setups:register
+ \xmlsetup{#1}{xml:setups:assemblename}
+ % not really needed if we just use setups
+ \expanded{\texcommand[stp:x:\currentSETUPfullname]{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:setups:basics
+ \xmlinclude{#1}{include}{filename}%
+ \xmlsetsetup {#1} {
+ sequence|string|variable|assignments|keywords|content|displaymath|index|math|
+ nothing|file|position|reference|csname|destination|triplet|word|
+ resolve|parameter|constant|inherit|parameter|define
+ } {xml:setups:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{setups}{xml:setups:basics}
+
+\unexpanded\def\loadsetups{\complexorsimple\loadsetups}
+
+\let\loadedsetups\empty % we load more setups, setups:<name>
+
+\def\simpleloadsetups
+ {\doifnotmode{no-setup-main}{\complexloadsetups[cont-en.xml]}}
+
+\def\complexloadsetups[#1]%
+ {\doifsomething{#1}
+ {\doonlyonce{setups:#1}
+ {\doglobal\prependtocommalist{setups:#1}\loadedsetups % last overloads first
+ \xmlloadonly{setups:#1}{#1}{setups}%
+ \xmlfilter{setups:#1}{/interface/command/command(xml:setups:register)}}}} % qualified path saves > 50% runtime
+
+\newif\ifshortsetup
+
+\unexpanded\def\setup {\shortsetupfalse\doshowsetup}
+\unexpanded\def\showsetup {\shortsetupfalse\doshowsetup}
+\unexpanded\def\shortsetup{\shortsetuptrue \doshowsetup}
+\unexpanded\def\setupsetup{\dodoubleargument\getparameters[\??stp]}
+
+%unexpanded\def\showsetupinlist#1#2#3{\shortsetupfalse\showsetupindeed{#3}\par}
+\unexpanded\def\showsetupinlist#1#2#3{\shortsetupfalse\xmlsetup{#3}{xml:setups:typeset}\par}
+
+% todo: only references in lists
+
+\def\doshowsetup
+ {\dosingleempty\dodoshowsetup}
+
+\def\dodoshowsetup[#1]%
+ {\iffirstargument
+ \dododoshowsetup{#1}%
+ \else
+ \expandafter\dododoshowsetup
+ \fi}
+
+\def\dododoshowsetup#1% this will trigger 'used'
+ {\registersort[texcommand][stp:x:#1]%
+ \showsetupindeed{#1}}
+
+% \def\showsetupindeed#1%
+% {\xmlfilterlist{\loadedsetups}{interface/command[@name='#1']/command(xml:setups:typeset)}}
+
+% \def\showsetupindeed#1%
+% {\xmlfilterlist{\loadedsetups}{/interface/command['#1' == (@type=='environment' and 'start' or '') .. @name]/command(xml:setups:typeset)}}
+
+% \setelementnature[setup][display]
+% \setelementnature[setup][mixed]
+
+\def\showsetupindeed#1%
+ {\startelement[setup][name=#1]%
+ \startelement[noexport][comment={setup definition #1}]
+ \xmlfilterlist{\loadedsetups}{/interface/command['#1' == (@type=='environment' and '\e!start' or '') .. @name]/command(xml:setups:typeset)}%
+ \stopelement
+ \stopelement}
+
+\unexpanded\def\placesetup {\placelistofsorts[texcommand][\c!criterium=\v!used]}
+\unexpanded\def\placeallsetups{\placelistofsorts[texcommand][\c!criterium=\v!all ]}
+
+\let\placeeverysetup\placeallsetups
+
+%D Typesetting:
+
+\setupxml
+ [%\c!method=mkiv, % mixed mode
+ \c!default=\v!hidden, % ignore elements that are not defined
+ \c!compress=\v!yes, % strip comment
+ \c!entities=\v!yes] % replace entities
+
+\newcounter\currentSETUPargument
+\newcounter\maximumSETUPargument
+
+\def\currentSETUPwidth{0pt}
+
+\startxmlsetups xml:setups:typeset
+ \getvalue{\e!start setuptext}
+ \tttf
+ \nohyphens
+ \veryraggedright
+ \doglobal\newcounter\currentSETUPargument
+ \xdef\maximumSETUPargument{\xmlcount{#1}{/arguments/*}}
+ \edef\currentSETUPhash{\xmlatt{#1}{hash}}
+ \bgroup
+ \enablemode[setups-pass-one]%
+ \doif {\xmlatt{#1}{generated}} {yes} {
+ \ttsl
+ }
+ \letterbackslash
+ \doif {\xmlatt{#1}{type}} {environment} {
+ \e!start
+ }
+ \xmlfilter{#1}{/sequence/first()}
+ \ignorespaces
+ \egroup
+ \ifshortsetup
+ % nothing
+ \else
+ \xmldoif{#1}{/arguments} {
+ \bgroup
+ \enablemode[setups-pass-one]
+ \doglobal\newcounter\currentSETUPargument
+ \ignorespaces
+ \xmlfilter{#1}{/arguments/text()}
+ \egroup
+ }
+ \doif {\xmlatt{#1}{type}} {environment} {
+ \bgroup
+ \enablemode[setups-pass-one]%
+ \hskip.5em\unknown\hskip.5em
+ \doif {\xmlatt{#1}{generated}} {yes} {
+ \ttsl
+ }
+ \tex{\e!stop}
+ \xmlfilter{#1}{/sequence/first()}
+ \ignorespaces
+ \egroup
+ }
+ \endgraf
+ \xmldoif{#1}{/arguments} {
+ \bgroup
+ \enablemode[setups-pass-two]
+ \doglobal\newcounter\currentSETUPargument
+ %\blank[\v!line] % packed mode (we could do \startunpacked ...)
+ \godown[.75\lineheight]
+ \switchtobodyfont[\v!small]
+ \ignorespaces\xmlfilter{#1}{/arguments/text()}\endgraf
+ \egroup
+ }
+ \fi
+ \getvalue{\e!stop setuptext}
+\stopxmlsetups
+
+\setupsetup
+ [\c!before=,
+ \c!after=,
+ \c!command=\setup,
+ \c!criterium=\v!used]
+
+\startxmlsetups xml:setups:resolve
+ \ignorespaces
+ \xmlfilterlist{\loadedsetups}{/interface/define[@name='\xmlatt{#1}{name}']/first()}
+\stopxmlsetups
+
+%D This is the first pass; here we generate the top line.
+
+\startxmlsetups xml:setups:define
+ \ignorespaces\xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:setups:sequence
+ \ignorespaces\xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:setups:string
+ \xmlatt{#1}{value}\ignorespaces
+\stopxmlsetups
+
+\startxmlsetups xml:setups:content \showSETUPcomponent{#1}{content} {content} \stopxmlsetups
+\startxmlsetups xml:setups:displaymath \showSETUPcomponent{#1}{displaymath}{display math}\stopxmlsetups
+\startxmlsetups xml:setups:index \showSETUPcomponent{#1}{index} {index} \stopxmlsetups
+\startxmlsetups xml:setups:math \showSETUPcomponent{#1}{math} {math} \stopxmlsetups
+\startxmlsetups xml:setups:nothing \showSETUPcomponent{#1}{nothing} {nothing} \stopxmlsetups
+\startxmlsetups xml:setups:file \showSETUPcomponent{#1}{file} {file name} \stopxmlsetups
+\startxmlsetups xml:setups:position \showSETUPcomponent{#1}{position} {position} \stopxmlsetups
+\startxmlsetups xml:setups:reference \showSETUPcomponent{#1}{reference} {reference} \stopxmlsetups
+\startxmlsetups xml:setups:csname \showSETUPcomponent{#1}{csname} {csname} \stopxmlsetups
+\startxmlsetups xml:setups:destination \showSETUPcomponent{#1}{destination}{destination} \stopxmlsetups
+\startxmlsetups xml:setups:triplet \showSETUPcomponent{#1}{triplet} {triplet} \stopxmlsetups
+\startxmlsetups xml:setups:word \showSETUPcomponent{#1}{word} {word} \stopxmlsetups
+
+\def\showSETUPcomponent#1#2#3%
+ {\doifelsemode{setups-pass-one}
+ {\getvalue{showSETUP#2}{#1}}
+ {\simpleSETUPargument{#3}}}
+
+%D This is the second pass; here we generate the table.
+
+\unexpanded\def\startfirstSETUPcolumn#1%
+ {\bgroup
+ \advance\leftskip 2em
+ \noindent\llap{\hbox to 2em{#1\hss}}}
+
+\unexpanded\def\stopfirstSETUPcolumn
+ {\endgraf
+ \egroup}
+
+\unexpanded\def\startsecondSETUPcolumn#1#2%
+ {\bgroup
+ \advance\hangindent\dimexpr\currentSETUPwidth+2.5em\relax
+ \noindent \hbox to \hangindent{#1\hss\hbox to 2.5em{\hss#2\hss}}}
+
+\unexpanded\def\stopsecondSETUPcolumn
+ {\endgraf
+ \egroup}
+
+\def\secondSETUPcolumn#1#2%
+ {\startsecondSETUPcolumn{#1}{#2}\stopsecondSETUPcolumn}
+
+\def\previousSETUPargument{\currentSETUPargument}
+
+\startxmlsetups xml:setups:parameter:measure
+ \setbox0=\hbox{\c!setup!reserved!{\xmlatt{#1}{name}}}
+ \ifdim\wd0>\currentSETUPwidth\xdef\currentSETUPwidth{\the\wd0}\fi
+\stopxmlsetups
+
+\startxmlsetups xml:setups:assignments
+ \doifelsemode{setups-pass-one} {
+ \showSETUPassignment{#1}
+ } {
+ \xdef\currentSETUPwidth{0pt}%
+ \bgroup
+ \xmlfilter{#1}{/parameter/command(xml:setups:parameter:measure)}
+ \egroup
+ \startfirstSETUPcolumn{\showSETUPnumber}%
+ \ignorespaces
+ \xmldoifelse{#1}{/(parameter|inherit)}{
+ \xmlflush{#1}
+ } {
+ ...
+ }
+ \let\previousSETUPargument\currentSETUPargument
+ \stopfirstSETUPcolumn
+ \blank[\v!halfline]
+ \ignorespaces
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:setups:keywords
+ \doifelsemode{setups-pass-one} {
+ \showSETUPkeyword{#1}
+ } {
+ \startfirstSETUPcolumn{\showSETUPnumber}%
+ \ignorespaces
+ \xmlflush{#1}
+ \let\previousSETUPargument\currentSETUPargument
+ \stopfirstSETUPcolumn
+ \blank[\v!halfline]
+ \ignorespaces
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:setups:parameter
+ \startsecondSETUPcolumn{\c!setup!reserved!{\xmlatt{#1}{name}}}{=}
+ \ignorespaces
+ \xmlflush{#1}
+ \doifmode{interface:setup:defaults} {
+ \ifx\currentSETUPhash\empty \else
+ \begingroup
+ % todo, make a one level expansion of parameter
+ \let\emwidth \relax
+ \let\exheight\relax
+ \edef\currentSETUPvalue{\csname named\currentSETUPhash parameter\endcsname\empty{\xmlatt{#1}{name}}}
+ \ifx\currentSETUPvalue\empty \else
+ =\space
+ \detokenize\expandafter{\currentSETUPvalue}
+ \fi
+ \endgroup
+ \fi
+ }
+ \stopsecondSETUPcolumn
+ \ignorespaces
+\stopxmlsetups
+
+\startxmlsetups xml:setups:constant
+ \doifelsemode {setups-pass-one} {
+ } {
+ \doif {\xmlatt{#1}{default}} {yes} {
+ \underbar % next needs to be {braced}
+ }
+ {\c!setup!reserved!{\xmlatt{#1}{type}}}
+ \space
+ \ignorespaces
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:setups:variable
+ \doifelsemode {setups-pass-one} {
+ \expanded{\setupintfont{\xmlatt{#1}{value}}}\ignorespaces
+ } {
+ \c!setup!reserved!{\xmlatt{#1}{value}}
+ \space
+ \ignorespaces
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:setups:inherit
+ \secondSETUPcolumn {
+ \c!setup!text!{\getmessage{setup}{inherits}}
+ \enspace
+ \letterbackslash
+ \xmlatt{#1}{name}
+ } {}
+ \ignorespaces
+\stopxmlsetups
+
+\def\simpleSETUPargument#1%
+ {\startfirstSETUPcolumn{\showSETUPnumber}%
+ \c!setup!internal!{#1}%
+ \stopfirstSETUPcolumn
+ \blank[\v!halfline]
+ \ignorespaces}
+
+\c!setup!definereserved {cd:command} {\c!setup!internal!{\getmessage{setup}{command}}}
+\c!setup!definereserved {cd:dimension} {\c!setup!internal!{\getmessage{setup}{dimension}}}
+\c!setup!definereserved {cd:file} {\c!setup!internal!{\getmessage{setup}{file}}}
+\c!setup!definereserved {cd:name} {\c!setup!internal!{\getmessage{setup}{identifier}}}
+\c!setup!definereserved {cd:character} {\c!setup!internal!{\getmessage{setup}{character}}}
+\c!setup!definereserved {cd:mark} {\c!setup!internal!{\getmessage{setup}{mark}}}
+\c!setup!definereserved {cd:number} {\c!setup!internal!{\getmessage{setup}{number}}}
+\c!setup!definereserved {cd:reference} {\c!setup!internal!{\getmessage{setup}{reference}}}
+\c!setup!definereserved {cd:plural} {\c!setup!internal!{\getmessage{setup}{plural}}}
+\c!setup!definereserved {cd:singular} {\c!setup!internal!{\getmessage{setup}{singular}}}
+\c!setup!definereserved {cd:text} {\c!setup!internal!{\getmessage{setup}{text}}}
+\c!setup!definereserved {cd:formula} {\c!setup!internal!{\getmessage{setup}{formula}}}
+\c!setup!definereserved {cd:file} {\c!setup!internal!{\getmessage{setup}{file}}}
+\c!setup!definereserved {cd:matrix} {\c!setup!internal!{\getmessage{setup}{matrix}}}
+\c!setup!definereserved {cd:list} {\c!setup!internal!{\getmessage{setup}{list}}}
+\c!setup!definereserved {cd:section} {\c!setup!internal!{\getmessage{setup}{section}}}
+
+\c!setup!definereserved {cd:noargument} {\c!setup!command! {}}
+\c!setup!definereserved {cd:oneargument} {\c!setup!command! {\#1}}
+\c!setup!definereserved {cd:twoarguments} {\c!setup!command! {\#1\#2}}
+\c!setup!definereserved {cd:threearguments} {\c!setup!command! {\#1\#2\#3}}
+
+%D Auxiliary.
+
+\unexpanded\def\showSETUP#1#2#3%
+ {\bgroup
+ \doglobal\increment\currentSETUPargument
+ \setbox0=\hbox
+ {\doifelse{\xmlatt{#1}{list}}{yes}{#3}{#2}}%
+ \setbox2=\hbox to \wd0
+ {\hss
+ \raise1ex\hbox
+ {\tx\ifcase\maximumSETUPargument\relax
+ \or*\else\currentSETUPargument
+ \fi}%
+ \hss}%
+ \setbox4=\hbox to \wd0
+ {\hss
+ \lower2ex\hbox
+ \bgroup
+ \txx\doif{\xmlatt{#1}{optional}}{yes}{\c!setup!internal!{\getmessage{setup}{optional}}}%
+ \egroup
+ \hss}%
+ \ht2\ht\strutbox
+ \dp4\dp\strutbox
+ \hskip.5em\hsmash{\box0}\hsmash{\box4}\box2%
+ \egroup
+ \ignorespaces}
+
+\def\showSETUPnumber
+ {\doglobal\increment\currentSETUPargument
+ \hbox to 2em
+ {\ifcase\maximumSETUPargument\relax
+ \or*\else\currentSETUPargument
+ \fi
+ \hss}}
+
+\def\showSETUPassignment #1{\showSETUP{#1}{[.\lower.5ex\hbox{=}.]} {[..,.\lower.5ex\hbox{=}.,..]}}
+\def\showSETUPkeyword #1{\showSETUP{#1}{[...]} {[...,...]}}
+\def\showSETUPargument #1{\showSETUP{#1}{\leftargument..\rightargument} {\leftargument..,...,..\rightargument}}
+\def\showSETUPdisplaymath#1{\showSETUP{#1}{\$\$...\$\$} {\$\$...\$\$}}
+\def\showSETUPindex #1{\showSETUP{#1}{\leftargument...\rightargument} {\leftargument..+...+..\rightargument}}
+\def\showSETUPmath #1{\showSETUP{#1}{\$...\$} {\$...\$}}
+\def\showSETUPnothing #1{\showSETUP{#1}{...} {}}
+\def\showSETUPfile #1{\showSETUP{#1}{~...~} {}}
+\def\showSETUPposition #1{\showSETUP{#1}{(...)} {(...,...)}}
+\def\showSETUPreference #1{\showSETUP{#1}{[...]} {[...,...]}}
+\def\showSETUPcsname #1{\showSETUP{#1}{{\c!setup!command!{}}} {}}
+\def\showSETUPdestination#1{\showSETUP{#1}{[\leftargument..[ref]\rightargument]}{[..,\leftargument..[ref,..]\rightargument,..]}}
+\def\showSETUPtriplet #1{\showSETUP{#1}{[x:y:z=]} {[x:y:z=,..]}}
+\def\showSETUPword #1{\showSETUP{#1}{\leftargument...\rightargument} {\leftargument.. ... ..\rightargument}}
+\def\showSETUPcontent #1{\showSETUP{#1}{\leftargument...\rightargument} {\leftargument.. ... ..\rightargument}}
+
+% A prelude to a rewrite and some more:
+
+% \definetype[parametercommand][\v!type]
+% \definetype[parameterkey] [\v!type]
+% \definetype[parametervalue] [\v!type][\c!space=\v!on]
+
+\definetype[parametercommand]
+\definetype[parameterkey]
+\definetype[parametervalue] [\c!space=\v!on]
+
+\setuptype [parametercommand] [\c!color=darkmagenta]
+\setuptype [parametervalue] [\c!color=darkyellow]
+
+\startxmlsetups xml:setups:parameters:value
+ \edef\currentsetupparameterkey {\xmlatt{#1}{name}}
+ \edef\currentsetupparametervalue{\csname named\currentsetupparametercategory parameter\endcsname\currentsetupparameterinstance\currentsetupparameterkey}
+ \ifx\currentsetupparameterinstance\empty
+ \expanded {
+ \NC \parameterkey {\currentsetupparameterkey}
+ \NC \parametervalue{\detokenize\expandafter{\currentsetupparametervalue}}
+ \NC \NR
+ }
+ \else\ifx\currentsetupparametervalue\empty
+ \else
+ \edef\currentsetupparameterdefault{\csname named\currentsetupparametercategory parameter\endcsname\empty\currentsetupparameterkey}
+ \ifx\currentsetupparametervalue\currentsetupparameterdefault
+ % skip
+ \else
+ \expanded {
+ \NC \parameterkey {\currentsetupparameterkey}
+ \NC \parametervalue{\detokenize\expandafter{\currentsetupparametervalue}}
+ \NC \NR
+ }
+ \fi
+ \fi\fi
+\stopxmlsetups
+
+\startxmlsetups xml:setups:parameters:values
+ \blank[big]
+ \expanded {
+ \parametercommand {
+ \currentsetupparametercommand
+ \space:\space
+ \ifx\currentsetupparameterinstance\empty
+ defaults
+ \else
+ \currentsetupparameterinstance
+ \fi
+ }
+ }
+ \blank[big,samepage]
+ \starttabulate[|l|p|]
+ \xmlall
+ {#1}
+ {/interface/command[@name=='\currentsetupparametercommand']/arguments/assignments/parameter/command(xml:setups:parameters:value)}
+ \ifnum\noftabulaterows = \zerocount
+ \NC \parameterkey{no specific settings} \NC \NC \NR
+ \fi
+ \stoptabulate
+\stopxmlsetups
+
+\starttexdefinition showrootvalues [#1]
+ \edef\currentsetupparametercategory{#1}
+ \edef\currentsetupparametercommand{setup#1}
+ \let\currentsetupparameterinstance\empty
+ \xmlsetup{\loadedsetups}{xml:setups:parameters:values}
+\stoptexdefinition
+
+\starttexdefinition showinstancevalues [#1]#2[#3]
+ \edef\currentsetupparametercategory{#1}
+ \edef\currentsetupparametercommand{setup#1}
+ \edef\currentsetupparameterinstance{#3}
+ \xmlsetup{\loadedsetups}{xml:setups:parameters:values}
+\stoptexdefinition
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/x-set-12.mkiv b/tex/context/modules/mkiv/x-set-12.mkiv
new file mode 100644
index 000000000..c60445313
--- /dev/null
+++ b/tex/context/modules/mkiv/x-set-12.mkiv
@@ -0,0 +1,267 @@
+%D \module
+%D [ file=x-set-12,
+%D version=2004.10.31,
+%D remark=setupx.tex: 1998.07.20 and later,
+%D title=\CONTEXT\ Setup Definitions,
+%D subtitle=Macro Definitions,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% included loading overhead
+%
+% 2.55 / 2.40 (luatex)
+% 1.90 / 1.80 (luajittex)
+
+% \newif\ifcachedcommand
+% \newif\ifcalledcommand
+%
+% \cachedcommandtrue
+% \calledcommandtrue
+%
+% \usemodule[speedtest]
+
+\usemodule[set-11]
+
+\unprotect
+
+% \starttext
+% \setup{installlanguage}
+% \placesetup
+% \stoptext
+
+\definecolor[TitleColor][r=.375,g=.125,b=.125]
+\definecolor[TitleColor][r=.125,g=.375,b=.125]
+\definecolor[TitleColor][r=.125,g=.125,b=.375]
+\definecolor[TitleColor][r=.375,g=.375,b=.125]
+\definecolor[TitleColor][r=.375,g=.125,b=.375]
+\definecolor[TitleColor][r=.125,g=.375,b=.375]
+
+\definecolor[TitleColor][r=.25,g=.20,b=.15]
+\definecolor[TitleColor][r=.25,g=.15,b=.20]
+\definecolor[TitleColor][r=.20,g=.15,b=.25]
+\definecolor[TitleColor][r=.20,g=.25,b=.15]
+\definecolor[TitleColor][r=.15,g=.20,b=.25]
+\definecolor[TitleColor][r=.15,g=.25,b=.20]
+
+\startinterface english \loadsetups[cont-en.xml] \stopinterface
+\startinterface dutch \loadsetups[cont-nl.xml] \stopinterface
+\startinterface german \loadsetups[cont-de.xml] \stopinterface
+\startinterface french \loadsetups[cont-fr.xml] \stopinterface
+\startinterface italian \loadsetups[cont-it.xml] \stopinterface
+\startinterface czech \loadsetups[cont-cs.xml] \stopinterface
+\startinterface romanian \loadsetups[cont-ro.xml] \stopinterface
+
+\startinterface dutch \definecolor[LocalColor][r=.75,g=.25,b=.25] \stopinterface
+\startinterface english \definecolor[LocalColor][r=.25,g=.75,b=.25] \stopinterface
+\startinterface german \definecolor[LocalColor][r=.25,g=.25,b=.75] \stopinterface
+\startinterface french \definecolor[LocalColor][r=.75,g=.75,b=.25] \stopinterface
+\startinterface czech \definecolor[LocalColor][r=.75,g=.25,b=.75] \stopinterface
+\startinterface italian \definecolor[LocalColor][r=.25,g=.75,b=.75] \stopinterface
+\startinterface romanian \definecolor[LocalColor][r=.5,g=.4,b=.3] \stopinterface
+% \definecolor[LocalColor][r=.5,g=.3,b=.4]
+% \definecolor[LocalColor][r=.4,g=.3,b=.5]
+% \definecolor[LocalColor][r=.4,g=.5,b=.3]
+% \definecolor[LocalColor][r=.3,g=.4,b=.5]
+% \definecolor[LocalColor][r=.3,g=.5,b=.4]
+
+\startinterface english \definecolor[TitleColor][r=.375,g=.125,b=.125] \stopinterface
+\startinterface dutch \definecolor[TitleColor][r=.125,g=.375,b=.125] \stopinterface
+\startinterface german \definecolor[TitleColor][r=.125,g=.125,b=.375] \stopinterface
+\startinterface french \definecolor[TitleColor][r=.375,g=.375,b=.125] \stopinterface
+\startinterface italian \definecolor[TitleColor][r=.375,g=.125,b=.375] \stopinterface
+\startinterface czech \definecolor[TitleColor][r=.125,g=.375,b=.375] \stopinterface
+\startinterface romanian \definecolor[TitleColor][r=.25,g=.20,b=.15] \stopinterface
+% \definecolor[TitleColor][r=.25,g=.15,b=.20]
+% \definecolor[TitleColor][r=.20,g=.15,b=.25]
+% \definecolor[TitleColor][r=.20,g=.25,b=.15]
+% \definecolor[TitleColor][r=.15,g=.20,b=.25]
+% \definecolor[TitleColor][r=.15,g=.25,b=.20]
+
+\definecolor [lightgray] [s=.9]
+\definecolor [darkgray] [s=.1]
+
+\usetypescript[palatino]
+\setupbodyfont[palatino,9pt]
+
+\defineoverlay
+ [cover]
+ [\hbox to \paperwidth{\hss\reuseMPgraphic{cover+back}}]
+
+\defineoverlay
+ [back]
+ [\hbox to \paperwidth{\reuseMPgraphic{cover+back}\hss}]
+
+\startreusableMPgraphic{cover+back}
+ numeric h, w ; path p, q, r ; color f, d ; pair s ;
+ h := OverlayHeight ; w := 2*OverlayWidth ;
+ r := unitsquare xyscaled (w,h) ;
+ fill r withcolor \MPcolor{lightgray} ;
+ set_grid(w,h,w/8,w/16) ;
+ forever :
+ s := center r randomized (w,h) ;
+ if new_on_grid(xpart s, ypart s) :
+ s := (dx,dy) ;
+ p := fullsquare xyscaled(w/4,w/8) ;
+ q := (-4w,ypart ulcorner p) -- .5[ulcorner p, urcorner p] -- (4w,ypart urcorner p) ;
+ q := q shifted (0,-w/24) ;
+ p := p randomized (w/40,w/40) ;
+ q := q randomized (0,w/100) ;
+ q := q cutafter (p cutafter point 3 of p) ;
+ q := q cutbefore (p cutbefore point 3 of p) ;
+ d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ;
+ f := \MPcolor{lightgray} randomized (.5,.9) ;
+ pickup pencircle scaled (w/100) ;
+ fill p shifted s withcolor f ;
+ draw p shifted s withcolor d ;
+ draw q shifted s withcolor d ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+ setbounds currentpicture to r ;
+\stopreusableMPgraphic
+
+\definelayout
+ [titlepage]
+ [\c!backspace=1cm,
+ \c!topspace=1cm,
+ \c!width=\v!middle,
+ \c!height=\v!middle,
+ \c!header=0pt,
+ \c!footer=0pt]
+
+\setuplayout
+ [\c!backspace=2cm,
+ \c!topspace=1.5cm,
+ \c!header=0cm,
+ \c!footer=0cm,
+ \c!width=\v!middle,
+ \c!height=\v!middle]
+
+\setuppagenumbering
+ [\c!alternative=\v!doublesided]
+
+\setupsetup
+ [\c!criterium=\v!all]
+
+\setupframedtexts
+ [setuptext]
+ [\c!before=\blank,
+ \c!after=\blank,
+ \c!frame=\v!on,
+ \c!rulethickness=1pt,
+ \c!framecolor=TitleColor]
+
+\setupunderbar
+ [\c!rulethickness=1pt,
+ \c!rulecolor=TitleColor]
+
+\starttext
+
+\setupbackgrounds
+ [\v!rightpage]
+ [\c!background=cover]
+
+\setuplayout
+ [titlepage]
+
+\startsetups text:commands
+ \startinterface dutch \strut commando's \par \stopinterface
+ \startinterface english \strut commands \par \stopinterface
+ \startinterface german \strut befehle \par \stopinterface
+ \startinterface french \strut commandes \par \stopinterface
+ \startinterface czech \strut p\v{r}ikazy \par \stopinterface
+ \startinterface italian \strut comandi \par \stopinterface
+ \startinterface romanian \strut comenzile \par \stopinterface
+\stopsetups
+
+\startsetups text:uppercase
+ \startinterface dutch NL\stopinterface
+ \startinterface english EN\stopinterface
+ \startinterface german DE\stopinterface
+ \startinterface french FR\stopinterface
+ \startinterface czech CS\stopinterface
+ \startinterface italian IT\stopinterface
+ \startinterface romanian RO\stopinterface
+\stopsetups
+
+\startsetups text:lowercase
+ \startinterface dutch \strut nl / nederlands \par \stopinterface
+ \startinterface english \strut en / english \par \stopinterface
+ \startinterface german \strut de / deutsch \par \stopinterface
+ \startinterface french \strut fr / fran\c{c}ais \par \stopinterface
+ \startinterface czech \strut cs / \v{c}esk\'y \par \stopinterface
+ \startinterface italian \strut it / italiano \par \stopinterface
+ \startinterface romanian \strut ro / rom\^{a}n\u{a} \par \stopinterface
+\stopsetups
+
+\startmakeup[\v!standard]
+ \dontcomplain
+ \setupalign[\v!left]
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 150pt]\setstrut
+ \setups[text:uppercase]
+ \stopcolor
+\stopmakeup
+
+\setuplayout % needed ?
+
+\setupbackgrounds
+ [\v!rightpage]
+ [\c!background=]
+
+\startmakeup[\v!standard]
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 100pt]\setstrut
+ \setupalign[\v!left]
+ \strut Con\TeX t \par
+ \definedfont[RegularBold at 50pt]\setstrut
+ \setups[text:commands]
+ \vfill
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setups[text:lowercase]
+ \par \strut \currentdate \par
+ \stopcolor
+\stopmakeup
+
+\protect
+
+\placeeverysetup
+
+\unprotect
+
+\page[\v!yes,\v!blank,\v!right,\v!left]
+
+\setuplayout
+ [titlepage]
+
+\setupbackgrounds
+ [\v!leftpage]
+ [\c!background=back]
+
+\startmakeup[\v!standard][\c!page=]
+ \dontcomplain
+ \startcolor[TitleColor]
+ \definedfont[RegularBold at 24pt]\setupinterlinespace
+ \setupalign[\v!left]
+ \vfill
+ PRAGMA ADE \par
+ Ridderstraat 27 \par
+ 8061GH Hasselt NL \par
+ www.pragma-ade.com \par
+ \stopcolor
+\stopmakeup
+
+\protect
+
+\stoptext
diff --git a/tex/context/modules/mkiv/x-steps.mkiv b/tex/context/modules/mkiv/x-steps.mkiv
new file mode 100644
index 000000000..29b3f7eaa
--- /dev/null
+++ b/tex/context/modules/mkiv/x-steps.mkiv
@@ -0,0 +1,102 @@
+%D \module
+%D [ file=m-steps,
+%D version=2001.05.28,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Step Charts \& Tables,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The \XML\ interface. This module can be made way more efficient
+%D in \MKIV\ using textext but it makes only sense to do this when
+%D I really need it in a demanding application. Probably half of the
+%D code in m-steps.tex can go.
+
+\usemodule[m][steps]
+
+\unprotect
+
+\installcorenamespace {xmlstepchart}
+\installcorenamespace {xmlsteptable}
+
+\def\xmlstepchartdirective#1{\executeifdefined{\??xmlstepchart#1}\gobbletwoarguments} % {#2}{#3}
+\def\xmlsteptabledirective#1{\executeifdefined{\??xmlsteptable#1}\gobbletwoarguments} % {#2}{#3}
+
+\setvalue{\??xmlstepchart charts}{\setsomevalue\@@STPC}
+\setvalue{\??xmlstepchart cells}{\setsomevalue\@@STEC}
+\setvalue{\??xmlstepchart texts}{\setsomevalue\@@STET}
+\setvalue{\??xmlstepchart lines}{\setsomevalue\@@STEL}
+
+\setvalue{\??xmlsteptable tables}{\setsomevalue\@@STPT}
+\setvalue{\??xmlsteptable cells}{\setsomevalue\@@STEC}
+\setvalue{\??xmlsteptable texts}{\setsomevalue\@@STET}
+\setvalue{\??xmlsteptable lines}{\setsomevalue\@@STEL}
+
+\startxmlsetups xml:ct:define
+ \xmlsetsetup {#1} {ct:*} {xml:ct:*}
+ % \xmlsetsetup {#1} {ct:stepaligntable/cells} {xml:ct:stepaligntable:cells}
+ % \xmlsetsetup {#1} {ct:stepaligntable/lines} {xml:ct:stepaligntable:lines}
+\stopxmlsetups
+
+\xmlregisterns{ct}{stepcharts}
+
+\xmlregistersetup{xml:ct:define}
+
+\startxmlsetups xml:ct:prep
+ \expanded{\prep[\xmltoparameters{#1}]}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:ct:text
+ \expanded{\text[\xmltoparameters{#1}]}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:ct:texts
+ \expanded{\texts[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}}
+\stopxmlsetups
+
+\startxmlsetups xml:ct:cell
+ \expanded{\cell[\xmltoparameters{#1}]}{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:ct:cells
+ \expanded{\cells[\xmltoparameters{#1}]}{\xmltext{#1}{/top}} {\xmltext{#1}{/bot}}
+\stopxmlsetups
+
+\startxmlsetups xml:ct:lines
+ \expanded{\startlines[\xmltoparameters{#1}]}
+ \xmlflush{#1}
+ \stoplines
+\stopxmlsetups
+
+\startxmlsetups xml:ct:steptable
+ \expanded{\startSTEPtable[\xmltoparameters{#1}]}
+ \xmlflush{#1}
+ \stopSTEPtable
+\stopxmlsetups
+
+\startxmlsetups xml:ct:stepchart
+ \expanded{\startSTEPchart[\xmltoparameters{#1}]}
+ \xmlflush{#1}
+ \stopSTEPchart
+\stopxmlsetups
+
+% \startxmlsetups xml:ct:stepaligntable
+% \expanded{\startSTEPaligntable[\xmltoparameters{#1}]}
+% \xmlflush{#1}
+% \stopSTEPaligntable
+% \stopxmlsetups
+%
+% \startxmlsetups xml:ct:stepaligntable:cells
+% \expanded{\cells[\xmltoparameters{#1}]} {\xmltext{#1}{/ct:c1}} {\xmltext{#1}{/ct:c2}} {\xmltext{#1}{/ct:c3}}
+% \stopxmlsetups
+%
+% \startxmlsetups xml:ct:stepaligntable:lines
+% \expanded{\setupSTEPlines[\xmltoparameters{#1}]}
+% \xmlflush{#1}
+% \stopxmlsetups
+
+\protect \endinput
diff --git a/tex/context/modules/mkiv/x-udhr.mkiv b/tex/context/modules/mkiv/x-udhr.mkiv
new file mode 100644
index 000000000..e081bfd59
--- /dev/null
+++ b/tex/context/modules/mkiv/x-udhr.mkiv
@@ -0,0 +1,98 @@
+%D \module
+%D [ file=x-udhr,
+%D version=2011.06.11,
+%D title=\CONTEXT\ Modules,
+%D subtitle=Unicode Language Test Files,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D The XML files can be fetched from: \from[http://unicode.org/udhr/].
+
+\startmodule[udhr]
+
+\startxmlsetups udhr:basics
+ \xmlsetsetup {#1} {*} {udhr:*}
+\stopxmlsetups
+
+\xmlregistersetup{udhr:basics}
+
+\startxmlsetups udhr:udhr
+
+ \mainlanguage[\xmlatt{#1}{language}]
+
+ \starttitle[title=\xmltext{#1}{/title}]
+ \xmlfirst{#1}{/preamble}
+ \xmlall{#1}{/article}
+ \stoptitle
+
+\stopxmlsetups
+
+\startxmlsetups udhr:preamble
+ \startsubject[title=\xmltext{#1}{/title}]
+ \xmlall{#1}{/*)}
+ \stopsubject
+\stopxmlsetups
+
+\startxmlsetups udhr:article
+ \startsubject[title=\xmltext{#1}{/title}]
+ \xmlall{#1}{/*)}
+ \stopsubject
+\stopxmlsetups
+
+\startxmlsetups udhr:orderedlist
+ \startitemize[n]
+ \xmlflush{#1}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups udhr:listitem
+ \startitem
+ \xmlflush{#1}
+ \stopitem
+\stopxmlsetups
+
+\startxmlsetups udhr:para
+ \xmlflush{#1}
+ \par
+\stopxmlsetups
+
+\setupbodyfont
+ [dejavu,10pt]
+
+\setuplayout
+ [width-=middle,
+ height=middle,
+ footer=0cm,
+ header=1.5cm]
+
+\setupwhitespace
+ [big]
+
+\setuphead
+ [chapter]
+ [header=high,
+ style=\bfb,
+ align=middle]
+
+\setuphead
+ [section]
+ [style=\bfa,
+ align=middle]
+
+\setuptolerance
+ [verytolerant]
+
+\continueifinputfile{x-udhr.mkiv}
+
+% todo: when argument given then process it
+
+\starttext
+ \xmlprocessfile{main}{udhr_nld.xml}{}
+\stoptext
+
+\stopmodule
diff --git a/tex/context/modules/mkiv/x-xfdf.mkiv b/tex/context/modules/mkiv/x-xfdf.mkiv
new file mode 100644
index 000000000..460220ed9
--- /dev/null
+++ b/tex/context/modules/mkiv/x-xfdf.mkiv
@@ -0,0 +1,72 @@
+%D \module
+%D [ file=x-xfdf,
+%D version=2011.09.07,
+%D title=\CONTEXT\ XML Modules,
+%D subtitle=\XFDF,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is a revival of using \XFDF, but now in a more \MKIV-ish way. We
+%D supported it long ago already in \MKII\ but never used it at a large
+%D scale (not that much user interest anyway).
+
+\startmodule[xfdf]
+
+% see xfdf-001.xfdf and xfdf-001.tex
+
+% %D Possible speedup but hardly worth the trouble.
+%
+% \startluacode
+%
+% local hashes = { } table.setmetatableindex(hashes,function(t,k) local v = { } t[k] = v return v end)
+%
+% function xml.functions.xfdf_collect_values(root)
+% local hash = hashes[root]
+% for c in xml.collected(root,"/xfdf/fields/field/value") do
+% hash[xml.parent(c).at.name] = c
+% end
+% end
+%
+% function xml.functions.xfdf_get_values(root,name)
+% return hashes[root][name]
+% end
+%
+% function lxml.xfdf_get_values(root,name)
+% xml.sprint(hashes[lxml.id(root)][name])
+% end
+%
+% \stopluacode
+%
+% \def\xfdfvalue#1#2%
+% {\ctxlua{lxml.xfdf_get_values("#1","#2")}}
+
+\startxmlsetups xfdf:define
+ \xmlsetsetup{#1}{*}{xfdf:*}
+ % \xmlfilter {#1}{./function(xfdf_collect_values)}
+\stopxmlsetups
+
+\xmlregisterns{xfdf}{http://ns.adobe.com/xfdf/}
+
+\xmlregisterdocumentsetup{xfdf}{xfdf:define}
+
+\startxmlsetups xfdf:value
+ \xmlflush{#1}
+\stopxmlsetups
+
+\def\xfdfload #1#2{\xmlloadonly{#1}{#2}{xfdf}}
+\def\xfdfvalue#1#2{\xmlfirst{#1}{/xfdf/fields/field[@name='#2']/value}}
+\def\xfdftext #1#2{\xmlfirst{#1}{/xfdf/fields/field[@name='#2']/value/paragraphs()}}
+
+% \startxmlsetups xfdf:b
+% \bold{\xmlflush{#1}}
+% \stopxmlsetups
+
+% \xfdfload {whatever}{xfdf-001.xfdf}
+% \xfdfvalue{whatever}{somefield}
+
+\stopmodule